您现在的位置是:首页 > 技术教程 正文

前端导出word文件的多种方式、前端导出excel文件

admin 阅读: 2024-03-30
后台-插件-广告管理-内容页头部广告(手机)

文章目录

  • 纯前借助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",
  • 1
  • 2
  • 3
  • 4

具体代码:(先看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>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137

前端通过模板字符串导出word文件

包依赖:

"file-saver": "^2.0.5",
  • 1

代码

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 ( ` 上报信息 上报信息 事件类型: ${reportInfoDetail['eventTypeName']} 地点定位: ${reportInfoDetail['locationAddress']} 上报时间: ${reportInfoDetail['reportTime']} 人员姓名: ${reportInfoDetail['reportUserName']} 联系方式: ${reportInfoDetail['reportUserPhone']} 图片附件 ${reportInfoDetail['picIds']?.map((res1: any, idx1: any) => { return ` %20%20%20%20%20%20%20%20${((idx1%20+%201)%20%%202%20==%200)%20?%20``%20:%20''} %20%20%20%20%20%20%20%20` %20%20%20%20}) %20%20%20%20} %20%20%20%20%20%20 %20%20%20%20%20%20事件描述 %20%20%20%20%20%20${reportInfoDetail['description']} %20%20%20%20 %20%20%20%20${reportInfoDetail.assignInfo.length%20!=%200%20? %20%20%20%20%20%20` %20%20%20%20%20%20<div%20class="fromBox"> %20%20%20%20%20%20<div%20class="formTitle_first">指派信息</div> %20%20%20%20%20%20<div%20class="formTitle_second%20%20display_flex">指派信息</div> %20%20%20%20%20%20<div%20class="formContent_box"> %20%20%20%20%20%20%20%20<div%20class="formContent_box_title">指派单位: %20%20%20%20%20%20%20%20%20%20${reportInfoDetail.assignInfo.map((res:%20any,%20idx:%20any)%20=>%20{ %20%20%20%20%20%20%20%20return%20` %20%20%20%20%20%20%20%20%20%20%20%20%20%20 %20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20${res.departmentName} %20%20%20%20%20%20%20%20%20%20%20%20%20%20 %20%20%20%20%20%20%20%20%20%20%20%20%20%20` %20%20%20%20%20%20}) %20%20%20%20%20%20} %20%20%20%20%20%20%20%20 %20%20%20%20%20%20 %20%20%20%20%20%20 %20%20%20%20%20%20%20%20%20%20指派时间: %20%20%20%20%20%20%20%20%20%20${!!reportInfoDetail?.assignInfo[0]?.assignTime%20?%20reportInfoDetail?.assignInfo[0]?.assignTime%20:%20""} %20%20%20%20%20%20 %20%20%20%20 %20%20%20%20%20%20`:%20'' %20%20%20%20}%20%20 %20%20%20%20<div%20class="fromBox"> %20%20%20%20%20%20<div%20class="formTitle_first">处置信息</div> %20%20%20%20%20%20${reportInfoDetail.handleInfo.length%20!=%200%20? %20%20%20%20%20%20reportInfoDetail.handleInfo.map((itm:%20any,%20idx:%20any)%20=>%20{ %20%20%20%20%20%20%20%20return%20` %20%20%20%20%20%20%20%20单位${idx%20+%201}${itm['claimDepartmentName']} %20%20%20%20%20%20%20%20签收信息 %20%20%20%20%20%20%20%20 %20%20%20%20%20%20%20%20%20%20 %20%20%20%20%20%20%20%20%20%20%20%20签收单位:${itm['claimDepartmentName']} %20%20%20%20%20%20%20%20%20%20 %20%20%20%20%20%20%20%20%20%20 %20%20%20%20%20%20%20%20%20%20%20%20签收时间:${itm['claimTime']} %20%20%20%20%20%20%20%20%20%20 %20%20%20%20%20%20%20%20 %20%20%20%20%20%20%20%20图片附件 %20%20%20%20%20%20%20%20 %20%20%20%20%20%20%20%20%20%20${itm['handleTime']%20!=%20null%20? %20%20%20%20%20%20%20%20%20%20%20%20itm['handlePicIds']?.map((res1:%20any,%20idx1:%20any)%20=>%20{ %20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20` %20%20%20%20%20%20%20%20%20%20 %20%20%20%20%20%20%20%20%20%20${(idx1%20+%201)%20%%202%20==%200%20?%20``%20:%20''} %20%20%20%20%20%20%20%20%20%20` %20%20%20%20%20%20%20%20%20%20%20%20})%20:%20`` %20%20%20%20%20%20%20%20%20%20} %20%20%20%20%20%20%20%20 %20%20%20%20%20%20%20%20处置描述 %20%20%20%20%20%20%20%20${itm.handleTime%20!=%20null%20?%20itm['handleDescription']%20:%20`未上传处置`} %20%20%20%20%20%20%20%20上报信息 %20%20%20%20%20%20%20%20 %20%20%20%20%20%20%20%20%20%20 %20%20%20%20%20%20%20%20%20%20%20%20上报单位:${itm['claimDepartmentName']} %20%20%20%20%20%20%20%20%20%20 %20%20%20%20%20%20%20%20%20%20 %20%20%20%20%20%20%20%20%20%20%20%20上报时间:${itm['handleTime']%20!=%20null%20?%20itm['handleTime']%20:%20''} %20%20%20%20%20%20%20%20%20%20 %20%20%20%20%20%20%20%20 %20%20%20%20%20%20%20%20
%20%20%20%20%20%20%20%20
` %20%20%20%20%20%20})%20:%20'无数据' %20%20%20%20} %20%20%20%20</div%20> %20%20%20%20<div%20class="fromBox"> %20%20%20%20%20%20<div%20class="formTitle_first">其他信息</div> %20%20%20%20%20%20<div%20class="formContent_box%20%20display_flex"> %20%20%20%20%20%20%20%20<span%20class="formContent_box_title">信息状态:</span> %20%20%20%20%20%20%20%20<span> %20%20%20%20%20%20%20%20%20%20${list[eventState%20-%201].desc} %20%20%20%20%20%20%20%20%20%20${reportInfoDetail?.finishTime%20!=%20null%20?%20reportInfoDetail?.finishTime%20:%20''} %20%20%20%20%20%20%20%20</span> %20%20%20%20</div> %20%20%20%20<div%20class="formContent_box%20%20display_flex"> %20%20%20%20%20%20<span%20class="formContent_box_title">采纳状态:</span> %20%20%20%20%20%20<span>${reportInfoDetail.acceptInfo%20==%20null%20?%20"未采纳"%20:%20`已采纳(${reportInfoDetail.acceptInfo.integral})`}</span> %20%20%20%20</div> %20%20</div> %20%20</div%20> </body%20> </html%20> %20%20` %20%20) } const%20loadFile%20=%20(info:%20any)%20=>%20{ %20%20let%20html%20=%20model(info.reportInfoDetail,%20info.list,%20info.eventState) %20%20let%20blob%20=%20new%20Blob([html],%20{%20type:%20"application/msword;charset=utf-8"%20}); %20%20//%20let%20blob%20=%20htmlDocx.asBlob(html,%20{%20orientation:%20"landscape"%20}); %20%20FileSaver.saveAs(blob,%20"信息管理文件.doc"); } export%20{ %20%20loadFile };
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225

前端导出%20excel文件,node-xlsx导出文件,行列合并

%20

导出效果:

需要的依赖: node-xlsx

"node-xlsx": "^0.23.0",
  • 1

代码:

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); };
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
标签:
声明

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

在线投稿:投稿 站长QQ:1888636

后台-插件-广告管理-内容页尾部广告(手机)
关注我们

扫一扫关注我们,了解最新精彩内容

搜索