前端导出word文件的多种方式、前端导出excel文件
夜空孤狼啸 2024-06-18 14:03:08 阅读 96
文章目录
纯前借助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); };
声明
本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。