純前借助word模板端導(dǎo)出word文件 (推薦)
先看效果:
這是頁面中的table
這是導(dǎo)出后的效果:
使用模板導(dǎo)出
需要的依賴:
npm 自行安裝,需要看官網(wǎng)的具體參數(shù)自行去github上面找對(duì)應(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() 是一一對(duì)應(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: '中國(guó)',
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公共文件夾下面了)。我們?cè)趯?dǎo)出的時(shí)候,會(huì)根據(jù)此模板來導(dǎo)出對(duì)應(yīng)的數(shù)據(jù)
// 拋出異常
if (error) {
throw error;
}
// 創(chuàng)建一個(gè)PizZip實(shí)例,內(nèi)容為模板的內(nèi)容
let zip = new PizZip(content);
// 創(chuàng)建并加載docx templater實(shí)例對(duì)象
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;
}
// 生成一個(gè)代表docxtemplater對(duì)象的zip文件(不是一個(gè)真實(shí)的文件,而是在內(nèi)存中的表示)
let out = doc.getZip().generate({
type: 'blob',
mimeType: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
});
// 將目標(biāo)文件對(duì)象保存為目標(biāo)類型的文件,并命名
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: '地點(diǎn)定位',
key: 'locationAddress',
},
{
name: '上報(bào)時(shí)間',
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">上報(bào)信息</div>
<div class="formTitle_second">上報(bào)信息</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">地點(diǎn)定位:</span>
<span>${reportInfoDetail['locationAddress']}</span>
</div>
<div class="formContent_box display_flex" style="display:flex">
<span class="formContent_box_title">上報(bào)時(shí)間:</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">指派時(shí)間:</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>簽收時(shí)間:${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">上報(bào)信息</div>
<div class="formContent_box display_flex"
style="width:32vw;justify-content: space-between;">
<div>
<span>上報(bào)單位:${itm['claimDepartmentName']}</span>
</div>
<div>
<span>上報(bào)時(shí)間:${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文章來源:http://www.zghlxwxcb.cn/news/detail-843042.html
"node-xlsx": "^0.23.0",
代碼:文章來源地址http://www.zghlxwxcb.cn/news/detail-843042.html
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);
};
到了這里,關(guān)于前端導(dǎo)出word文件的多種方式、前端導(dǎo)出excel文件的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!