|
|
@@ -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()
|