Pārlūkot izejas kodu

生命体征增加单人导出excel

xiongxing 1 mēnesi atpakaļ
vecāks
revīzija
460acbd4b8
1 mainītis faili ar 141 papildinājumiem un 1 dzēšanām
  1. 141 1
      src/views/elderly/assess/vital-sign/index.vue

+ 141 - 1
src/views/elderly/assess/vital-sign/index.vue

@@ -45,7 +45,14 @@
       :columns="VitalSignColumns"
       :queryParams="queryParams"
       @detail="openDetail"
-    />
+      :opWidth="220"
+    >
+      <template #next="{ scope }">
+        <el-button link type="primary" @click="handleRowExport(scope)">
+          <Icon icon="ep:download" class="mr-5px" /> 导出
+        </el-button>
+      </template>
+    </Table2>
 
     <!-- 分页 -->
     <Pagination
@@ -67,6 +74,10 @@ import Form from './Form.vue'
 import Export from './Export.vue'
 import Detail from './Detail.vue'
 import { useUserStore } from '@/store/modules/user'
+import * as XLSX from 'xlsx-js-style'
+import { getDictLabel } from '@/utils/dict'
+import { DICT_TYPE } from '@/utils/dict'
+import { formatTime } from '@/utils'
 defineOptions({ name: 'VitalSign' })
 const userStore = useUserStore()
 const message = useMessage() // 消息弹窗
@@ -152,6 +163,135 @@ const handleDelete = async () => {
   } catch {}
 }
 
+/** 单行导出 */
+const handleRowExport = (row: any) => {
+  const wb = XLSX.utils.book_new()
+  const headers = [
+    '体温℃',
+    '脉搏/分',
+    '呼吸/分',
+    '收缩压mmHg',
+    '舒张压mmHg',
+    '血压饱和度%',
+    '血糖mmol/L',
+    '体重kg',
+    '大便',
+    '小便',
+    '备注',
+    '测量人',
+    '测量时间',
+    '测量日期'
+  ]
+  const colCount = headers.length
+  const sexText = getDictLabel(DICT_TYPE.SYSTEM_USER_SEX, row.elderSex) || row.elderSex
+  const measuringDateText = row.measuringDate ? formatTime(row.measuringDate, 'yyyy-MM-dd') : ''
+
+  // 标题行
+  const titleRow: string[] = new Array(colCount).fill('')
+  titleRow[0] = '生命体征'
+
+  // 基本信息行:姓名 / 性别 / 床号 均匀分布,中间留空列
+  const infoItems = [
+    { label: '姓名:', value: row.elderName || '', start: 0, span: 4 },
+    { label: '性别:', value: sexText, start: 5, span: 4 },
+    { label: '床号:', value: row.bedName || '', start: 10, span: 4 }
+  ]
+  const infoRow: string[] = new Array(colCount).fill('')
+  infoItems.forEach((item) => {
+    infoRow[item.start] = item.label + item.value
+  })
+
+  // 表头行
+  const headerRow = headers
+
+  // 数据行
+  const dataRow = [
+    row.temperature,
+    row.pulse,
+    row.respiratoryRate,
+    row.systolicPressure,
+    row.diastolicPressure,
+    row.bloodOxygenSaturation,
+    row.bloodSugar,
+    row.weight,
+    row.stool,
+    row.urinate,
+    row.remark,
+    row.measuringName,
+    row.measuringTime,
+    measuringDateText
+  ]
+
+  const ws = XLSX.utils.aoa_to_sheet([titleRow, infoRow, headerRow, dataRow])
+
+  // 合并单元格
+  ws['!merges'] = [
+    { s: { r: 0, c: 0 }, e: { r: 0, c: colCount - 1 } },
+    ...infoItems.map((item) => ({ s: { r: 1, c: item.start }, e: { r: 1, c: item.start + item.span - 1 } }))
+  ]
+
+  // 列宽
+  ws['!cols'] = [
+    { wch: 18 },
+    { wch: 10 },
+    { wch: 10 },
+    { wch: 10 },
+    { wch: 10 },
+    { wch: 10 },
+    { wch: 10 },
+    { wch: 10 },
+    { wch: 10 },
+    { wch: 10 },
+    { wch: 10 },
+    { wch: 10 },
+    { wch: 10 },
+    { wch: 15 }
+  ]
+
+  // 行高
+  ws['!rows'] = [{ hpt: 38 }, { hpt: 28 }, { hpt: 32 }, { hpt: 28 }]
+
+  const range = XLSX.utils.decode_range(ws['!ref'] || '')
+  const headerFill = {
+    patternType: 'solid',
+    fgColor: { rgb: 'FFD9D9D9' }
+  }
+  const border = {
+    top: { style: 'thin', color: { rgb: 'FF000000' } },
+    bottom: { style: 'thin', color: { rgb: 'FF000000' } },
+    left: { style: 'thin', color: { rgb: 'FF000000' } },
+    right: { style: 'thin', color: { rgb: 'FF000000' } }
+  }
+
+  for (let R = range.s.r; R <= range.e.r; R++) {
+    for (let C = range.s.c; C <= range.e.c; C++) {
+      const cellRef = XLSX.utils.encode_cell({ r: R, c: C })
+      if (!ws[cellRef]) {
+        ws[cellRef] = { v: '', t: 's' }
+      }
+      const cell = ws[cellRef]
+      cell.s = cell.s || {}
+      cell.s.border = border
+      cell.s.alignment = { vertical: 'center', horizontal: 'center', wrapText: true }
+
+      if (R === 0) {
+        cell.s.font = { bold: true, sz: 18, name: '宋体' }
+      } else if (R === 1) {
+        cell.s.alignment = { vertical: 'center', horizontal: 'left', wrapText: true }
+        cell.s.font = { bold: true, sz: 11, name: '宋体' }
+      } else if (R === 2) {
+        cell.s.fill = headerFill
+        cell.s.font = { bold: true, sz: 11, name: '宋体' }
+      } else {
+        cell.s.font = { sz: 11, name: '宋体' }
+      }
+    }
+  }
+
+  XLSX.utils.book_append_sheet(wb, ws, '生命体征')
+  XLSX.writeFile(wb, `${row.elderName || '生命体征'}_${measuringDateText || ''}.xlsx`)
+}
+
 /** 初始化 **/
 onMounted(() => {
   getList()