当前位置: 首页 > news >正文

商业网站备案流程网推获客平台

商业网站备案流程,网推获客平台,创意产品设计作品图片,网站建设公司架构vue3实现包含表格的Word文件导出 近期遇到一个要求#xff0c;需要在网页上导出Word文档#xff0c;文档中有表格#xff0c;也有普通的数据#xff0c;查阅了很多资料#xff0c;总算比较完美的解决了#xff0c;记录一下 先上一下最终效果 演示视频 vue3项目根据Wor…vue3实现包含表格的Word文件导出 近期遇到一个要求需要在网页上导出Word文档文档中有表格也有普通的数据查阅了很多资料总算比较完美的解决了记录一下 先上一下最终效果 演示视频 vue3项目根据Word模板导出Word文件 当然个人的项目要比这个演示的视频复杂多了需要配合后端完成 实现过程主要参考了这篇文章 一、第三方库的安装 要实现Word的导出功能需要额外安装以下第三方包 dependencies: {angular-expressions: ^1.2.1,docx-preview: ^0.3.2,docxtemplater: ^3.49.1,docxtemplater-image-module-free: ^1.1.1,file-saver: ^2.0.5,lodash: ^4.17.21,pizzip: ^3.1.7,},版本安装最新的就行了这是我自己的目前最新的版本2024年8月 二、Word模板的创建 必须要有一个Word模板根据自己的需求创建我的模板如下 这个模板中有常规变量、图片变量和表格变量表格变量需要循环表格数据获取 1、普通变量 普通变量直接用{变量名}的形式放在模板中就行了注意这里的变量名必须与前端vue组件中的变量名保持一致 2、图片变量 图片变量用{%变量名}表示就是普通变量前加%符号 3、表格变量 通常情况下表格都是多行的也就是说需要循环遍历前端的表格数据表格数据的处理比较复杂处理步骤如下 需要循环的表格数据用{#变量名}开始用{/变量名}结束循环也就是{#tableData}和{/tableData}列变量用{变量名}表示也就是{order}、{col1}、{col}和{col3}、{col5} 看下我前端的tableData变量 const tableData ref([{ order: 0, col1: 合计, col: 6266, col3: 23, col5: 2 },{ order: 1, col1: 徐州, col: 706, col3: 1, col5: 0 },{ order: 2, col1: 苏州, col: 668, col3: 2, col5: 0 },{ order: 3, col1: 盐城, col: 624, col3: 2, col5: 0 },{ order: 4, col1: 南通, col: 518, col3: 0, col5: 0 },{ order: 5, col1: 连云港, col: 498, col3: 3, col5: 0 },{ order: 6, col1: 淮安, col: 490, col3: 3, col5: 1 },{ order: 7, col1: 常州, col: 458, col3: 1, col5: 0 },{ order: 8, col1: 泰州, col: 454, col3: 1, col5: 0 },{ order: 9, col1: 无锡, col: 433, col3: 2, col5: 0 },{ order: 10, col1: 南京, col: 400, col3: 2, col5: 1 },{ order: 11, col1: 扬州, col: 383, col3: 3, col5: 0 },{ order: 12, col1: 宿迁, col: 363, col3: 1, col5: 0 },{ order: 13, col1: 镇江, col: 271, col3: 2, col5: 0 }, ]);在看下最后生成的表格 创建好Word模板后放在静态文件夹中就行了 三、编写导出Word的工具函数 在utils文件夹中创建exportFile.js文件编写以下代码 // 引入基本模块 import Docxtemplater from docxtemplater; import PizZip from pizzip; import PizZipUtils from pizzip/utils/index.js; import { saveAs } from file-saver; // 图片模块 import ImageModule from docxtemplater-image-module-free; // 解析语法模块 import expressions from angular-expressions; import assign from lodash/assign; // 文档预览模块 import { renderAsync } from docx-preview;expressions.filters.lower function (input) {if (!input) return input;return input.toLowerCase(); };function angularParser(tag) {tag tag.replace(/^\.$/, this).replace(/(|)/g, ).replace(/(|)/g, );const expr expressions.compile(tag);return {get: function (scope, context) {let obj {};const scopeList context.scopeList;const num context.num;for (let i 0, len num 1; i len; i) {obj assign(obj, scopeList[i]);}return expr(scope, obj);},}; }// 加载文件 function loadFile(url, callback) {PizZipUtils.getBinaryContent(url, callback); }// 配置空值替换函数 作为配置参数可配置在setOptions中 function nullGetter(part, scopeManager) {if (!part.module) {return -null-;}if (part.module rawxml) {return ;}return --; }/*** 预览word,支持图片* param {Object} tempDocxPath 模板文件路径* param {Object} wordData 导出数据* param {Object} fileName 导出文件名* param {Arrsy} imgSize 自定义图片尺寸*/ export const getWordImage (tempDocxPath, wordData, imgSize, file) {// 本地word.docx文件需要放在public目录下loadFile(tempDocxPath, (error, content) {if (error) {throw error;}// 图片配置const imageOpts {getImage: function (tagValue, tagName) {return new Promise(function (resolve, reject) {PizZipUtils.getBinaryContent(tagValue, function (error, content) {if (error) {return reject(error);}return resolve(content);});});},getSize: function (img, tagValue, tagName) {const size imgSize[tagName] ? imgSize[tagName] : [150, 150];return size;},};let imageModule new ImageModule(imageOpts);const zip new PizZip(content);// 实例化有两种方式 这里是链式const doc new Docxtemplater().loadZip(zip).setOptions({// delimiters: { start: [[, end: ]] },paragraphLoop: true,linebreaks: true,nullGetter: nullGetter,parser: angularParser,}).attachModule(imageModule).compile();doc.renderAsync(wordData).then(() {const out doc.getZip().generate({type: blob,mimeType:application/vnd.openxmlformats-officedocument.wordprocessingml.document,});renderAsync(out, file);});}); };/*** 导出word,不支持图片* param {Object} tempDocxPath 模板文件路径* param {Object} wordData 导出数据* param {Object} fileName 导出文件名*/ export const exportWord (tempDocxPath, wordData, fileName) {// 本地word.docx文件需要放在public目录下loadFile(tempDocxPath, (error, content) {if (error) {throw error;}const zip new PizZip(content);// 没有配置解析语法深层次对象语法obj.xx.xx不可识别const doc new Docxtemplater(zip, {paragraphLoop: true,linebreaks: true,});doc.render(wordData);const out doc.getZip().generate({type: blob,mimeType:application/vnd.openxmlformats-officedocument.wordprocessingml.document,});// Output the document using Data-URIsaveAs(out, ${fileName}.docx);}); }/*** 导出word,支持图片* param {Object} tempDocxPath 模板文件路径* param {Object} wordData 导出数据* param {Object} fileName 导出文件名* param {Arrsy} imgSize 自定义图片尺寸*/ export const exportWordImage (tempDocxPath, wordData, fileName, imgSize) {// 本地word.docx文件需要放在public目录下loadFile(tempDocxPath, (error, content) {if (error) {throw error;}// 图片配置const imageOpts {getImage: function (tagValue, tagName) {return new Promise(function (resolve, reject) {PizZipUtils.getBinaryContent(tagValue, function (error, content) {if (error) {return reject(error);}return resolve(content);});});},getSize: function (img, tagValue, tagName) {const size imgSize[tagName] ? imgSize[tagName] : [150, 150]return size;},};let imageModule new ImageModule(imageOpts);const zip new PizZip(content);// 实例化有两种方式 这里是链式const doc new Docxtemplater().loadZip(zip).setOptions({// delimiters: { start: [[, end: ]] },paragraphLoop: true,linebreaks: true,nullGetter: nullGetter,parser: angularParser,}).attachModule(imageModule).compile();doc.renderAsync(wordData).then(function () {const out doc.getZip().generate({type: blob,mimeType:application/vnd.openxmlformats-officedocument.wordprocessingml.document,});saveAs(out, ${fileName}.docx);});}); } 这里有Word的预览以及Word的导出处理函数我直接参考的他人的没做修改可以自己根据需求进行修改后面有时间我再慢慢理解 四、前端页面预览和导出 先上代码我这里只写了个演示所有没有用路由什么的就是直接放在App.vue根组件中 script setup import { exportWordImage, getWordImage } from /utils/exportFile; import { ref } from vue;const dialogVisible ref(false); const startSchemeTemplate ref({name: 启动方案名称,time: 2023-12-12,scope: 1XXXX所有一、二次设备 2XXXX主变、XXXX主变XX管辖,projectAdjuster: 1XXXX,XXXX主变冲击五次、核相。2XXXXX设备冲击一次XXXXXXX二次定相。3XXXXXX,XXXX差动保护带负荷试验。XX管辖4XXXXXX备自投实跳试验。,condition: 1XXX启动范围内的所有一、二次设备施工结束验收合格监控信息与相应调控人员核对完备设备可以带电站内一次设备相位正确。2XXX待用XXXXXX、待用XXXXXX、待用XXXXXX、待用XXXXXX、待用XXXXXX、待用XXXXXX、待用XXXXXX、银标XXXXXX、银阳XXXXXX、银区XXXXXX、待用XXXXXX、待用XXXXXX、待用XXXXXX、XXXXXX开关保护按定值单整定并投入。3启动范围内所有设备均为冷备用状态。,stepAdjuster: 1.XXXXXX冲击一次、定相。2.XXXXXX一次设备冲击见附图2,imgPath: https://docxtemplater.com/puffin.png,tableData: [] }); const imgSize ref({imgPath: [150, 150],imgPath1: [550, 250], });const tableData ref([{ order: 0, col1: 合计, col: 6266, col3: 23, col5: 2 },{ order: 1, col1: 徐州, col: 706, col3: 1, col5: 0 },{ order: 2, col1: 苏州, col: 668, col3: 2, col5: 0 },{ order: 3, col1: 盐城, col: 624, col3: 2, col5: 0 },{ order: 4, col1: 南通, col: 518, col3: 0, col5: 0 },{ order: 5, col1: 连云港, col: 498, col3: 3, col5: 0 },{ order: 6, col1: 淮安, col: 490, col3: 3, col5: 1 },{ order: 7, col1: 常州, col: 458, col3: 1, col5: 0 },{ order: 8, col1: 泰州, col: 454, col3: 1, col5: 0 },{ order: 9, col1: 无锡, col: 433, col3: 2, col5: 0 },{ order: 10, col1: 南京, col: 400, col3: 2, col5: 1 },{ order: 11, col1: 扬州, col: 383, col3: 3, col5: 0 },{ order: 12, col1: 宿迁, col: 363, col3: 1, col5: 0 },{ order: 13, col1: 镇江, col: 271, col3: 2, col5: 0 }, ]);const htmlTitle ref(启动方案);const downLoad () {exportWordImage(../template.docx,startSchemeTemplate.value,htmlTitle.value,imgSize.value); };const goPreview () {dialogVisible.value true; };const file ref(null); const handleOpened () {startSchemeTemplate.value.tableData tableData.valuegetWordImage(../template.docx,startSchemeTemplate.value,imgSize.value,file.value); }; /scripttemplatediv styleheight: 90%; background: #fff; padding: 24pxdiv stylemargin-bottom: 17px; text-align: leftel-button typeprimary clickdownLoad 下载启动方案 /el-buttonel-button typeprimary clickgoPreview 预览启动方案 /el-button/divel-divider /div stylemargin-top: 24px!--搜索区域--el-form :modelstartSchemeTemplate label-width110pxel-row :gutter24el-col :span12el-form-item label启动方案名称el-inputv-modelstartSchemeTemplate.nameplaceholder请输入//el-form-item/el-colel-col :span12el-form-item label预定启动时间el-date-pickerv-modelstartSchemeTemplate.timetypedateplaceholder请选择//el-form-item/el-col/el-rowel-row :gutter24 styleheight: 280pxel-col :span12el-form-item label启动范围el-inputv-modelstartSchemeTemplate.scopeplaceholder请输入typetextarea:autosize{ minRows: 13.5, maxRows: 14 }//el-form-item/el-colel-col :span12el-form-item label调试项目el-inputv-modelstartSchemeTemplate.projectAdjusterplaceholder请输入typetextarea:autosize{ minRows: 13.5, maxRows: 14 }//el-form-item/el-col/el-rowel-row :gutter24 styleheight: 280pxel-col :span12el-form-item label启动条件el-inputv-modelstartSchemeTemplate.conditionplaceholder请输入typetextarea:autosize{ minRows: 13.5, maxRows: 14 }//el-form-item/el-colel-col :span12el-form-item label调试步骤el-inputv-modelstartSchemeTemplate.stepAdjusterplaceholder请输入typetextarea:autosize{ minRows: 13.5, maxRows: 14 }//el-form-item/el-col/el-row/el-form/div/divel-dialogv-modeldialogVisibleopenedhandleOpenedtitle流程图width1200pxtop5vhdiv classdocWrapdiv reffile/div/div/el-dialog /templatestyle scoped .btn {float: left;margin: 0 0 24px; } .docWrap {height: 700px;overflow: auto;clear: both; } /style 变量全部放在startSchemeTemplate这个响应式变量中根据前端的表单或者输入来更改模板中的数据把模板和模板中需要的数据对应起来看就更直观了 const startSchemeTemplate ref({name: 启动方案名称,time: 2023-12-12,scope: 1XXXX所有一、二次设备 2XXXX主变、XXXX主变XX管辖,projectAdjuster: 1XXXX,XXXX主变冲击五次、核相。2XXXXX设备冲击一次XXXXXXX二次定相。3XXXXXX,XXXX差动保护带负荷试验。XX管辖4XXXXXX备自投实跳试验。,condition: 1XXX启动范围内的所有一、二次设备施工结束验收合格监控信息与相应调控人员核对完备设备可以带电站内一次设备相位正确。2XXX待用XXXXXX、待用XXXXXX、待用XXXXXX、待用XXXXXX、待用XXXXXX、待用XXXXXX、待用XXXXXX、银标XXXXXX、银阳XXXXXX、银区XXXXXX、待用XXXXXX、待用XXXXXX、待用XXXXXX、XXXXXX开关保护按定值单整定并投入。3启动范围内所有设备均为冷备用状态。,stepAdjuster: 1.XXXXXX冲击一次、定相。2.XXXXXX一次设备冲击见附图2,imgPath: https://docxtemplater.com/puffin.png,tableData: [] });一言蔽之把Word模板中需要动态变化的数据放在响应式数据中这里是startSchemeTemplate然后根据响应式数据填充模板 预览和导出功能调用utils/exportFile.js中对应的方法就可以了 五、代码仓库 我已经把这个程序的所有代码和模板文件都传到了代码仓库有需要的可以自行下载理解
http://www.hkea.cn/news/14385500/

相关文章:

  • 微信小程序开发网站联雅网站建设公司
  • 什么直播可以做游戏视频网站吗电商推广都有哪些诀窍
  • 新网站关键词怎么优化网站代码制作软件
  • 微信订阅号网站开发wordpress 计算器插件
  • 淄博做网站的公司有哪些做煤层气的网站
  • 西安网络建站在线设计平台用户规模
  • 医疗网站有哪些网络管理系统提供网络管理需要的大量运算和记忆资源
  • 做网站外快站酷设计网站怎样下载图片
  • 网站备案号什么情况下被注销中国农村建设网站
  • 做网站和做公众号深圳做外贸网站公司哪家好
  • 手机网站建设报价表许昌企业网站去哪开发
  • 网站平台设计费用多少如何快速搭建个人网站
  • 我想阻止一个网站要怎么做旅游网站建设策划书案例
  • 游戏网站建设表格新余建站公司
  • 多网站绑定域名美团网站开发合作商
  • 高端网站建设系统vs做网站各种控件的使用
  • 六安做网站购买深圳网站定制开发
  • 龙岗区住房和建设局官方网站医生在线咨询
  • 室内装饰公司网站模板国外优质网站
  • 关于网站建设的标语服务网站排名咨询
  • 石家庄网站快速优化排名搜索引擎外部链接优化
  • 如何找工程项目信息做站群网站好优化吗
  • 广东建设网站首页深圳货拉拉
  • 响应式网站的原理零售空间设计公司
  • 品展示设计网站黄山旅游
  • wordpress里验证谷歌站长百度seo软件
  • 苏州免费模板建站怎么做seo网站推广
  • 宜兴网站制作红色展览馆设计主题及创意
  • 游戏工作室网络组建方案百度小程序优化合作公司
  • 在微信上做彩票网站吗天推广人的网站