文章目录
- 纯前借助word模板端导出word文件 (推荐)
- 使用模板导出
- 前端通过模板字符串导出word文件
- 前端导出 excel文件,node-xlsx导出文件,行列合并
纯前借助word模板端导出word文件 (推荐)
先看效果:
这是页面中的table
这是导出后的效果:
使用模板导出
需要的依赖:
npm 自行安装,需要看官网的具体参数自行去github上面找对应的参数
"docxtemplater": "^3.46.0","pizzip": "^3.1.6","jszip-utils": "^0.1.0","file-saver": "^2.0.5",
具体代码:(先看word模板,在看代码,word中的变量和代码中 doc.setData() 是一一对应的)
<template><div class="button-box"><a-space><a-button type="danger" @click="downWord2">模板导出word文件</a-button></a-space></div>
</template><script lang="ts">
import { defineComponent, onMounted, reactive, PropType, ref } from 'vue';
import { message } from 'ant-design-vue';
import moment from 'moment';
import { downloadPDF } from '../../../../utils/utils';
import { useTable } from './hooks/useTable';
import xlsx from 'node-xlsx';import docxtemplater from 'docxtemplater';
import PizZip from 'pizzip';
import JSZipUtils from 'jszip-utils';
import { saveAs } from 'file-saver';export default defineComponent({props: {/*** 基础数据*/baseData: {type: Object as PropType<{taskId: string;barcodeId: string;}>,default: {},},/*** 样本名称*/barcodeName: {type: String,},},setup(props) {let width = 100;const { barcodeName } = props;const { taskId, barcodeId } = props.baseData;const { tableConfig, tableConfigLeft, getDta } = useTable();onMounted(() => {barcodeName ? getDta(taskId, barcodeName) : '';});const tableValue = reactive({unit: '中国',date: undefined,sampleType: '你猜',people: '黄种人',name: '夜空',sex: '男',age: '25',work: '开发',id: '',jiance: '商品化试剂盒',date2: undefined,});const downWord2 = () => {let docxname = '导出word.docx';JSZipUtils.getBinaryContent('/test.docx', function (error: any, content: any) {// test.docx是模板(这里我放到public公共文件夹下面了)。我们在导出的时候,会根据此模板来导出对应的数据// 抛出异常if (error) {throw error;}// 创建一个PizZip实例,内容为模板的内容let zip = new PizZip(content);// 创建并加载docx templater实例对象let doc = new docxtemplater().loadZip(zip);// 设置模板变量的值 主要变量替换在这里doc.setData({name: tableValue.name,unit: tableValue.unit,date: moment(tableValue.date).format('YYYY-MM-DD'),sampleType: tableValue.sampleType,sex: tableValue.sex,age: tableValue.age,});try {// 用模板变量的值替换所有模板变量doc.render();} catch (error: any) {// 抛出异常let e = {message: error.message,name: error.name,stack: error.stack,properties: error.properties,};console.log(JSON.stringify({error: e,}),);throw error;}// 生成一个代表docxtemplater对象的zip文件(不是一个真实的文件,而是在内存中的表示)let out = doc.getZip().generate({type: 'blob',mimeType: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',});// 将目标文件对象保存为目标类型的文件,并命名saveAs(out, docxname);});};return {downWord2,getDta,tableConfig,tableConfigLeft,tableValue,downloadPDF,value4: ref('less'),};},
});
</script><style lang="less" scoped></style>
前端通过模板字符串导出word文件
包依赖:
"file-saver": "^2.0.5",
代码
import FileSaver from 'file-saver';
import htmlDocx from "html-docx-js/dist/html-docx"
import { G } from '@/global';
const { rootUrl, rbacToken } = G;
let cycle_info1 = [{name: '事件类型',key: 'eventTypeName',},{name: '地点定位',key: 'locationAddress',},{name: '上报时间',key: 'reportTime',},{name: '人员姓名',key: 'reportUserName',},{name: '联系方式',key: 'reportUserPhone',},
]const model = (reportInfoDetail: any, list: any, eventState: any) => {// console.log(reportInfoDetail, list, eventState);return (`<!DOCTYPE html><html><head><style>.MaxBox {padding: 0px 15px;overflow-y: auto;height: 50vh;}.fromBox {}.formTitle_first {color: #1c69f7;font-size: 23px;font-weight: bold;margin-bottom: 10px;}.formTitle_second {font-weight: bold;font-size: 16px;margin-bottom: 10px;}.formContent_box {margin-bottom: 5px;}.formContent_box_title {min-width: 60px;}.display_flex {display: flex;}</style>
</head><body><div class="MaxBox"><div class="fromBox"><div class="formTitle_first">上报信息</div><div class="formTitle_second">上报信息</div><div class="formContent_box display_flex" style="display:flex"><span class="formContent_box_title" >事件类型:</span><span>${reportInfoDetail['eventTypeName']}</span></div><div class="formContent_box display_flex" style="display:flex"><span class="formContent_box_title">地点定位:</span><span>${reportInfoDetail['locationAddress']}</span></div><div class="formContent_box display_flex" style="display:flex"><span class="formContent_box_title">上报时间:</span><span>${reportInfoDetail['reportTime']}</span></div><div class="formContent_box display_flex" style="display:flex"><span class="formContent_box_title">人员姓名:</span><span>${reportInfoDetail['reportUserName']}</span></div><div class="formContent_box display_flex" style="display:flex"><span class="formContent_box_title">联系方式:</span><span>${reportInfoDetail['reportUserPhone']}</span></div><div class="formTitle_second">图片附件</div><div class="formContent_box">${reportInfoDetail['picIds']?.map((res1: any, idx1: any) => {return `<img width='240' height='160' src="${rootUrl}/fyVolunteer/file/download/${res1}?rbacToken=${rbacToken}"style='margin-right:5px'/>${((idx1 + 1) % 2 == 0) ? `<br />` : ''}`})}</div><div class="formTitle_second">事件描述</div><div class="formContent_box">${reportInfoDetail['description']}</div></div>${reportInfoDetail.assignInfo.length != 0 ?`<div class="fromBox"><div class="formTitle_first">指派信息</div><div class="formTitle_second display_flex">指派信息</div><div class="formContent_box"><div class="formContent_box_title">指派单位:${reportInfoDetail.assignInfo.map((res: any, idx: any) => {return `<span style="margin-right:15px">${res.departmentName}</span>`})}</div ></div ><div class="formContent_box display_flex"><span class="formContent_box_title">指派时间:</span><span>${!!reportInfoDetail?.assignInfo[0]?.assignTime ? reportInfoDetail?.assignInfo[0]?.assignTime : ""}</span></div></div>`: ''} <div class="fromBox"><div class="formTitle_first">处置信息</div>${reportInfoDetail.handleInfo.length != 0 ?reportInfoDetail.handleInfo.map((itm: any, idx: any) => {return `<div class="formTitle_second">单位${idx + 1}:${itm['claimDepartmentName']}</div><div class="formTitle_second">签收信息</div><div class="formContent_box display_flex"style="width:32vw;justify-content: space-between;"><div><span>签收单位:${itm['claimDepartmentName']}</span></div><div><span>签收时间:${itm['claimTime']}</span></div></div ><div class="formTitle_second">图片附件</div><div class="formContent_box">${itm['handleTime'] != null ?itm['handlePicIds']?.map((res1: any, idx1: any) => {return `<img width="240" height="160"src="${rootUrl}/fyVolunteer/file/download/${res1}?rbacToken=${rbacToken}"style="margin-right:5px"/>${(idx1 + 1) % 2 == 0 ? `<br />` : ''}`}) : `<span style="color:#5558e8">无</span>`}</div><div class="formTitle_second">处置描述</div><div class="formContent_box">${itm.handleTime != null ? itm['handleDescription'] : `<span style="color:#5558e8">未上传处置</span>`}</div><div class="formTitle_second">上报信息</div><div class="formContent_box display_flex"style="width:32vw;justify-content: space-between;"><div><span>上报单位:${itm['claimDepartmentName']}</span></div><div><span>上报时间:${itm['handleTime'] != null ? itm['handleTime'] : ''}</span></div></div><br/>`}) : '无数据'}</div ><div class="fromBox"><div class="formTitle_first">其他信息</div><div class="formContent_box display_flex"><span class="formContent_box_title">信息状态:</span><span>${list[eventState - 1].desc}${reportInfoDetail?.finishTime != null ? reportInfoDetail?.finishTime : ''}</span></div><div class="formContent_box display_flex"><span class="formContent_box_title">采纳状态:</span><span>${reportInfoDetail.acceptInfo == null ? "未采纳" : `已采纳(${reportInfoDetail.acceptInfo.integral})`}</span></div></div></div >
</body >
</html >`)
}const loadFile = (info: any) => {let html = model(info.reportInfoDetail, info.list, info.eventState)let blob = new Blob([html], { type: "application/msword;charset=utf-8" });// let blob = htmlDocx.asBlob(html, { orientation: "landscape" });FileSaver.saveAs(blob, "信息管理文件.doc");
}export {loadFile
};
前端导出 excel文件,node-xlsx导出文件,行列合并
导出效果:
需要的依赖: node-xlsx
"node-xlsx": "^0.23.0",
代码:
const downXlsx = () => {let data = [[1, 222, '', '', '', ''],['', 2, 3, 4, 5, 6],['', 2, 3, 4, 5, 6],['', 2, 3, 4, 5, 6],['', 2, 3, 4, 5, 6],[22, 2, 3, 4, 5, 6],];// 行列合并规则 c:col 列 r:row 行const range0 = { s: { c: 0, r: 0 }, e: { c: 0, r: 4 } };const range1 = { s: { c: 1, r: 0 }, e: { c: 5, r: 0 } };const sheetOptions = {'!merges': [range0, range1],// cols 列宽大小'!cols': [{ wch: 5 }, { wch: 10 }, { wch: 15 }, { wch: 20 }, { wch: 30 }, { wch: 50 }],};//如果不需要格式,这里的sheetOptions可以省略不写let result = xlsx.build([{ name: 'sheet1', data }], { sheetOptions });const ab = Buffer.from(result, 'binary');const blob = new Blob([ab]);const blobUrl = URL.createObjectURL(blob);const a = document.createElement('a');a.href = blobUrl;a.download = '导出excel.xlsx';a.click();window.URL.revokeObjectURL(blobUrl);};