文章目錄
- 純前借助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);};