前端導(dǎo)出word文件的多種方式以及導(dǎo)出excel文件
先看效果:
這是頁面中的table
這是導(dǎo)出后的效果:
使用模板導(dǎo)出
需要的依賴:
npm 自行安裝,需要看官網(wǎng)的具體參數(shù)自行去github上面找對應(yīng)的參數(shù)
"docxtemplater": "^3.46.0", "pizzip": "^3.1.6", "jszip-utils": "^0.1.0", "file-saver": "^2.0.5",
具體代碼:(先看word模板,在看代碼,word中的變量和代碼中 doc.setData() 是一一對應(yīng)的)
<template> <div class="button-box"> <a-space> <a-button type="danger" @click="downWord2">模板導(dǎo)出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: { /** * 基礎(chǔ)數(shù)據(jù) */ 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: '開發(fā)', id: '', jiance: '商品化試劑盒', date2: undefined, }); const downWord2 = () => { let docxname = '導(dǎo)出word.docx'; JSZipUtils.getBinaryContent('/test.docx', function (error: any, content: any) { // test.docx是模板(這里我放到public公共文件夾下面了)。我們在導(dǎo)出的時候,會根據(jù)此模板來導(dǎo)出對應(yīng)的數(shù)據(jù) // 拋出異常 if (error) { throw error; } // 創(chuàng)建一個PizZip實例,內(nèi)容為模板的內(nèi)容 let zip = new PizZip(content); // 創(chuàng)建并加載docx templater實例對象 let doc = new docxtemplater().loadZip(zip); // 設(shè)置模板變量的值 主要變量替換在這里 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文件(不是一個真實的文件,而是在內(nèi)存中的表示) 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>
前端通過模板字符串導(dǎo)出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: '聯(lián)系方式', 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">聯(lián)系方式:</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/> ` }) : '無數(shù)據(jù)' } </div > <div class="fromBox"> <div class="formTitle_first">其他信息</div> <div class="formContent_box display_flex"> <span class="formContent_box_title">信息狀態(tài):</span> <span> ${list[eventState - 1].desc} ${reportInfoDetail?.finishTime != null ? reportInfoDetail?.finishTime : ''} </span> </div> <div class="formContent_box display_flex"> <span class="formContent_box_title">采納狀態(tài):</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 };
前端導(dǎo)出 excel文件,node-xlsx導(dǎo)出文件,行列合并
導(dǎo)出效果:
需要的依賴: 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], ]; // 行列合并規(guī)則 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 = '導(dǎo)出excel.xlsx'; a.click(); window.URL.revokeObjectURL(blobUrl); };
總結(jié)
到此這篇關(guān)于前端導(dǎo)出word文件的多種方式以及導(dǎo)出excel文件的文章就介紹到這了,更多相關(guān)前端導(dǎo)出word、excel文件內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Echarts折線圖設(shè)置線條顏色及線條以下代碼示例
最近項目需要,一直在使用Echarts視圖,現(xiàn)在遇到一個要修改echarts折線圖顏色的需求,下面這篇文章主要給大家介紹了關(guān)于Echarts折線圖設(shè)置線條顏色及線條以下區(qū)域漸變顏色的相關(guān)資料,需要的朋友可以參考下2024-02-02JavaScript DOM元素常見操作詳解【添加、刪除、修改等】
這篇文章主要介紹了JavaScript DOM元素常見操作,包括針對dom元素的添加、刪除、修改等相關(guān)操作實現(xiàn)技巧與注意事項,需要的朋友可以參考下2018-05-05JS數(shù)組push、unshift、pop、shift方法的實現(xiàn)與使用方法示例
這篇文章主要介紹了JS數(shù)組push、unshift、pop、shift方法,結(jié)合實例形式分析了JS數(shù)組push、unshift、pop、shift方法針對數(shù)組添加、刪除等相關(guān)操作技巧,需要的朋友可以參考下2020-04-04重載toString實現(xiàn)JS HashMap分析
用過Java的都知道,里面有個功能強大的數(shù)據(jù)結(jié)構(gòu)——HashMap,它能提供鍵與值的對應(yīng)訪問。不過熟悉JS的朋友也會說,JS里面到處都是hashmap,因為每個對象都提供了map[key]的訪問形式。2011-03-03