ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

amis Office Viewer 组件实战:在低代码页面中渲染、变量化、下载与打印 docx/xlsx 文档

amis Office Viewer 组件实战:在低代码页面中渲染、变量化、下载与打印 docx/xlsx 文档 amis Office Viewer 组件实战在低代码页面中渲染、变量化、下载与打印 docx/xlsx 文档【免费下载链接】amis前端低代码框架通过 JSON 配置就能生成各种页面。项目地址: https://gitcode.com/GitHub_Trending/am/amisOffice Viewer 是 amis 低代码框架中用于在页面内直接渲染 Office 文档目前支持 docx 与 xlsx的组件自 amis 2.9.0 起提供。本文以office-viewer组件为主线完整讲解其基本用法、Word 渲染配置项wordOptions、分页渲染、列表符号字体问题、变量替换与表格行循环、图片变量以及基于事件动作的下载、打印和配合input-file的文件预览方案。读完本文你可以直接在 amis 页面里通过纯 JSON 配置实现 Office 文档的在线预览与文档级交互能力。组件定位与适用范围office-viewer组件源码见 packages/amis/src/renderers/OfficeViewer.tsx用于渲染 Office 文档当前支持docxWord 文档渲染xlsx / csv / tsvExcel 电子表格渲染。该组件需要 amis2.9.0 及以上版本分页渲染page配置需要2.10.0 及以上版本图片变量支持需要2.10 及以上版本。Excel 渲染能力对应 amis 6.3 及以上版本其配置请参考 office-viewer-excel。从实现上看office-viewer组件底层由独立包 packages/office-viewer 提供渲染能力。组件通过env.fetcher以arraybuffer方式拉取文档再调用createOfficeViewer工厂函数自动识别文件类型根据文件扩展名或[Content_Types].xml中的 MIME 类型判断是 Word 还是 Excel见 createOfficeViewer.ts。本组件在页面中是以懒加载方式动态引入office-viewer模块的不会在首屏拖慢主包体积。基本用法一个最简单的office-viewer配置如下{ type: office-viewer, src: /examples/static/simple.docx, wordOptions: { padding: 8px, ignoreWidth: false } }其中src文档地址类型为 Api可支持变量插值组件会自动识别 docx/xlsx/csv/tsvwordOptionsWord 文档的渲染配置Excel 文档则使用excelOptions。仓库中的示例文档 simple.docx 即可直接用于验证上述配置。组件渲染时会在src变化、wordOptions变化或display变化时自动重新拉取与渲染文档见 OfficeViewer.tsx。Word 渲染配置项wordOptionsWord 渲染支持以下能力基础文本样式表格及表格样式内嵌图片列表注音链接文本框形状数学公式依赖 MathML需要比较新的浏览器支持分页渲染不支持的能力艺术字、域、对象、目录。这些能力对应的渲染实现集中在 packages/office-viewer/src/word/render 目录下例如注音renderRuby.ts、超链接renderHyperLink.ts、数学公式renderMath.ts、表格renderTable.ts、列表编号renderNumbering.ts等渲染主入口为 renderDocument.ts。wordOptions 属性表{ type: office-viewer, wordOptions: { padding: 8px, ignoreWidth: false } }属性名类型默认值说明classPrefixstringdocx-viewer渲染的 class 类前缀ignoreWidthbooleanfalse忽略文档里的宽度设置用于更好嵌入到页面里但会减低还原度paddingstring设置页面间距忽略文档中的设置bulletUseFontbooleantrue列表使用字体渲染请参考下面的乱码说明fontMappingobject字体映射是个键值对用于替换文档中的字体forceLineHeightstring设置段落行高忽略文档中的设置enableVarbooleantrue是否开启变量替换功能printOptionsobject针对打印的特殊设置可以覆盖其它所有设置项在底层实现 Word.ts 中WordRenderOptions还额外声明了一些未在文档属性表中列出的内部配置其默认值如下可作为深入理解行为时的参考内部配置项默认值说明ignoreHeighttrue是否忽略文档高度设置minLineHeight1.0最小行高printWaitTime100打印等待时间毫秒图片较多时可调大以保证打印前图片加载完renderHeadertrue是否渲染页眉renderFootertrue是否渲染页脚pageWrapPadding20分页模式下页面包裹的内边距ptpageMarginBottom20分页模式下每页之间的间距这些默认值在 Word.ts 的defaultRenderOptions中定义所有用户传入的wordOptions都会与该默认值合并updateOptions。分页渲染需要 amis 2.10.0 及以上版本。默认情况下Word 文档使用流式布局渲染这样能更好地融入到已有页面中但展现上会和原始文档有较大差异且不支持页眉页脚。如果希望呈现更接近桌面端 Word 的效果可以通过page: true开启分页渲染{ type: office-viewer, id: office-viewer-page, wordOptions: { page: true }, src: /examples/static/page.docx }仓库中的示例文档 page.docx 可用于验证分页渲染效果。开启page后底层会自动将ignoreHeight和ignoreWidth重置为false以尊重文档原始页面尺寸见 Word.ts。分页渲染的其它设置项属性名类型默认值说明pagebooleanfalse是否开启分页渲染pageMarginBottomnumber20页面上下间距pageBackgroundstring#FFF页面内背景色pageShadowbooleantrue是否显示阴影pageWrapbooleantrue是否显示页面包裹pageWrapBackgroundstring#ECECEC页面包裹的背景色zoomnumber缩放比例取值 0-1 之间zoomFitWidthbooleanfalse自适应宽度缩放如果设置了 zoom 将不会生效当page与pageWrap同时为true时渲染根节点会附加docx-viewer-wrapper类并应用pageWrapPadding内边距与pageWrapBackground背景色见 Word.ts。关于渲染效果差异目前的实现难以保证和本地 Word 渲染完全一致可能会遇到以下问题字体大小不一致单元格宽度不一致表格完全依赖浏览器渲染。如果追求完整效果的打印目前只能通过下载文件的方式用本地 Word 进行打印。列表符号出现乱码问题默认情况下列表左侧的符号使用字体渲染这样能最接近 Word 的渲染效果。但如果用户系统中没有对应字体就会显示乱码。解决方案是在 amis 渲染的页面中手动导入对应字体例如style font-face { font-family: Wingdings; src: url(./static/font/wingding.ttf); } font-face { font-family: Symbol; src: url(./static/font/symbol.ttf); } /style目前已知涉及Wingdings和Symbol两个字体可能还有别的仓库中已附带这两个字体的示例文件 wingding.ttf 和 symbol.ttf可参考其相对路径调整src。如果不想嵌入这两个字体可以在wordOptions中设置bulletUseFont: false改用其他方式渲染列表符号。变量替换文档中可以预先定义变量通过配置enableVar: true开启变量替换渲染时根据上下文数据动态替换变量。示例一个包含姓名、邮箱、手机号输入框和文档预览的表单{ type: form, title: , mode: inline, wrapWithPanel: false, body: [ { type: input-text, name: name, value: amis, label: 姓名 }, { type: input-email, name: email, label: 邮箱 }, { type: input-text, name: phone, label: 手机号 }, { type: office-viewer, id: office-viewer, src: /examples/static/info.docx, wordOptions: { enableVar: true, padding: 8px } } ] }关闭enableVar则显示原始文档{ type: office-viewer, id: office-viewer, src: /examples/static/info.docx, wordOptions: { padding: 8px } }变量说明变量写法为{{name}}其中name是变量名。变量内容可以是 amis 表达式例如{{DATETOSTR(TODAY(), YYYY-MM-DD)}}。在底层实现中变量替换通过evalVar完成amis 组件侧的evalVar会把{{...}}中的内容包装为${...}表达式再通过resolveVariableAndFilter结合当前上下文解析见 OfficeViewer.tsxoffice-viewer 包的replaceText则负责匹配{{([^{}])}}并调用evalVar取值见 Word.ts。变量未找到时渲染为空字符串。注意事项Word 经常会自作主张进行语法检查生成无关的标签导致变量替换出错。解决办法是忽略 Word 中所有的语法检查项即文档里不再有飘红的文字否则需要在模板文档中清理这些自动生成的标签。表格行循环针对表格支持循环语法。循环以{{#xxx}}开头、{{/}}结束目前不支持嵌套语法所以结束符号可以省略。示例一个同时包含「模板文档预览」「接口数据渲染」和「下载文档」的页面{ type: page, body: [ { type: office-viewer, id: office-viewer-table-list, src: /examples/static/table-list.docx, wordOptions: { padding: 8px } }, { type: service, api: /api/mock2/sample/mirror?json%7B%22users%22%3A%5B%7B%22name%22%3A%22u1%22%2C%22age%22%3A10%2C%22img%22%3A%22https%3A%2F%2Fsuda.cdn.bcebos.com%2Fimages%2Famis%2Fai-fake-face.jpg%22%7D%2C%7B%22name%22%3A%22u2%22%2C%22age%22%3A11%7D%5D%7D, body: [{ type: office-viewer, src: /examples/static/table-list.docx, wordOptions: { padding: 8px, enableVar: true, ignoreWidth: true }, trackExpression: ${users} }] }, { type: action, label: 下载文档, onEvent: { click: { actions: [ { actionType: saveAs, componentId: office-viewer-table-list } ] } } } ] }循环的语法以{{#name}}开始、{{/}}结束在这期间的变量会取循环内的值。底层实现中replaceTableRow会查找以{{#开头的循环变量名从数据中取出数组后对每一行克隆模板行cloneTr将循环项合入上下文并执行变量替换最后删除模板行见 replaceVar.ts。上述例子还使用到了trackExpression默认情况下如果设置了enableVar每次上层数据变化都会重新渲染文档如果文档较大可能会有性能问题。此时可以通过trackExpression限制只有指定数据变化时才重新渲染。从组件源码可以看到设置了trackExpression时仅当表达式求值结果变化才重渲染否则仅调用office.updateVariable()做轻量级的局部变量更新见 OfficeViewer.tsx。图片中的变量需要 amis 2.10 及以上版本。如果要将文档中的图片设置为变量需要右键对应的图片选择「查看可选文字」然后填入类似{{img}}的变量标识。渲染时图片将替换为img变量的 URL 地址。下图展示了在 Word 中设置图片「可选文字」的界面对应的配置示例{ type: form, title: , wrapWithPanel: false, body: [ { type: input-text, name: img, value: https://suda.cdn.bcebos.com/amis/images/alice-macaw.jpg, label: 图片地址 }, { type: office-viewer, id: office-viewer, src: /examples/static/image-alt-var.docx, wordOptions: { enableVar: true, padding: 8px } } ] }底层实现中replaceAlt会读取图片pic:cNvPr节点上的descr可选文字属性将其作为变量文本进行替换并在下载文档时真正把图片写入 zip 包通过saveNewImage生成新的 relationship 与 media 文件见 replaceVar.ts 与 Word.ts。不渲染模式通过配置display: false可以让文档不渲染。虽然不渲染但依然可以使用下载及打印功能。这在「只下载/打印、不预览」的场景下非常有用还能减少页面渲染开销。下载文档下载基于事件动作实现通过actionType: saveAs配合componentId触发[ { type: action, label: 下载文档, onEvent: { click: { actions: [ { actionType: saveAs, componentId: office-viewer-download } ] } } }, { type: office-viewer, id: office-viewer-download, display: false, src: /examples/static/simple.docx } ]saveAs动作还支持args.name指定下载文件名。组件侧收到saveAs动作后会调用office.download(args?.name || this.fileName)见 OfficeViewer.tsx。底层Word.download会读取word/document.xml在启用变量替换时先合并 Word 自动拆分产生的文本 runmergeRun再执行replaceVar完成表格循环与图片变量替换最后重新打包为 zip 并触发浏览器下载见 Word.ts。打印文档打印同样基于事件动作实现通过actionType: print触发[ { type: action, label: 打印, onEvent: { click: { actions: [ { actionType: print, componentId: office-viewer-print } ] } } }, { type: office-viewer, id: office-viewer-print, display: false, src: /examples/static/simple.docx } ]printOptions配置项可以用来自定义打印时的配置默认值为{ page: true, pageWrap: false, pageShadow: false, pageMarginBottom: 0, pageWrapPadding: undefined }也就是说打印时默认以分页模式渲染、去掉页面包裹与阴影、页间距为 0以获得更高的还原度。底层实现中Word.print会创建一个隐藏 iframe在其中以覆盖后的配置重新渲染文档并等待printWaitTime毫秒确保图片加载完成后再触发打印见 Word.ts。配合文件上传实现预览功能office-viewer可以配置和input-file相同的name从而直接预览用户上传的 docx 文件{ type: form, title: , wrapWithPanel: false, body: [ { type: input-file, name: file, label: File, asBlob: true, accept: .docx }, { type: office-viewer, id: office-viewer, name: file } ] }实现上当没有配置src而配置了name时组件会从表单数据中取出File对象用FileReader读取为ArrayBuffer后交给createOfficeViewer渲染见 OfficeViewer.tsx。需要注意input-file需要开启asBlob: true才能拿到本地文件对象。是否显示 loading通过loading: true配置可以强制显示加载中状态主要用于网络较慢的场景{ type: office-viewer, src: /examples/static/simple.docx, loading: true }从组件实现看loading 状态在文档拉取期间会自动置为truefetchWord中设置loading: true完成后恢复loading配置项与内置 Spinner 结合用于展示加载动画见 OfficeViewer.tsx。属性表属性名类型默认值说明srcApi文档地址loadingbooleanfalse是否显示 loading 图标enableVarboolean是否开启变量替换功能wordOptionsobjectWord 渲染配置动作表当前组件对外暴露以下特性动作其他组件可以通过指定actionType: 动作名称、componentId: 该组件id来触发这些动作动作配置可以通过args: {动作配置项名称: xxx}来配置具体的参数详细请查看事件动作。动作名称动作配置说明saveAsname?: string文件名下载文档print-打印文档进阶实践建议综合以上配置一个「文档模板 动态数据 下载/打印」的完整落地思路如下模板准备用 Word 制作 docx 模板正文使用{{name}}变量、表格行使用{{#users}}...{{/}}循环、图片通过「查看可选文字」填入{{img}}关闭 Word 语法检查避免自动标签破坏变量页面接入用office-viewer指向模板地址开启wordOptions.enableVar配合service或表单数据注入变量数据量较大时用trackExpression限制重渲染范围分页与还原追求桌面端效果时开启wordOptions.page: true并按需配置pageBackground、pageShadow、zoom等列表乱码规避页面中引入 Wingdings/Symbol 字体或设置bulletUseFont: false下载与打印通过saveAs、print事件动作实现必要时用display: false隐藏预览而保留能力本地文件预览与input-file共用name实现上传即预览。如需深入了解可以继续阅读组件封装实现packages/amis/src/renderers/OfficeViewer.tsx文档渲染引擎入口与渲染配置packages/office-viewer/src/Word.ts、packages/office-viewer/src/RenderOptions.ts变量/表格循环/图片变量实现packages/office-viewer/src/util/replaceVar.ts文件类型识别与工厂函数packages/office-viewer/src/createOfficeViewer.tsExcel 渲染配置office-viewer-excel示例文档simple.docx、page.docx、info.docx、table-list.docx、image-alt-var.docx 均位于 examples/static 目录【免费下载链接】amis前端低代码框架通过 JSON 配置就能生成各种页面。项目地址: https://gitcode.com/GitHub_Trending/am/amis创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表