1 mammoth
先找的是mammoth
这个插件yarn add mammoth
,版本是1,7.0
参考网上的示例使用如下:
import mammoth from "mammoth";
const vHtml = ref("")
const readExcelFromRemoteFile = (url) =>{
var xhr = new XMLHttpRequest();
xhr.open("get", url, true);
xhr.responseType = "arraybuffer";
xhr.onload = function () {
if (xhr.status == 200) {
mammoth.convertToHtml({ arrayBuffer: new Uint8Array(xhr.response) })
.then(function (resultObject) {
nextTick(() => {
// document.querySelector("#wordView").innerHTML =
// resultObject.value;
vHtml.value = resultObject.value;
});
});
}
};
xhr.send();
}
在word中设置的样式是
因为这个图片是做了文字环绕,因此他识别不了.
在网页端显示的如下面:
2 docx-preview
docx-preview
使用就不是很顺利
index:1 Uncaught (in promise) SyntaxError: The requested module '/psi/node_modules/.vite/deps/docx-preview.js?v=d111f2a1' does not provide an export named 'default'
jszip.min.js:13 Uncaught (in promise) Error: Can't read the data of 'the loaded zip file'. Is it in a supported JavaScript type (String, Blob, ArrayBuffer, etc) ?
at jszip.min.js:13
at async Function.load (open-xml-package.ts:26)
at async Function.load (word-document.ts:52)
at async renderAsync (docx-preview.ts:56)
使用这个组件,要装两个依赖包
yarn add docx-preview
参考了vue3+typescript 预览docx文件,这是我的版本用的0.3.0
,并不支持doc
格式
但是docx则可以显示,文件上传的同时,直接就可以渲染出来。这个我喜欢。
参考代码如下
<template>
<el-container>
<el-aside width="250px">
<el-header height="45px">
<div class="nav">
<el-button type="primary">保存</el-button>
</div>
</el-header>
<el-main>
<el-form :model="dataForm" label-suffix=":" label-position="top" style="margin-top: 10px;">
<el-form-item label="合同名称" prop="name">
<el-input v-model="dataForm.name" placeholder="请输入合同名称" clearable></el-input>
</el-form-item>
<el-form-item label="合同模板" prop="tpl">
<sc-upload-file v-model="dataForm.tpl" :limit="1" drag :on-change="handleChange" :auto-upload="false">
<el-icon class="el-icon--upload"><el-icon-upload-filled /></el-icon>
<div class="el-upload__text">
拖拽到这 或<em>点击上传</em>
</div>
</sc-upload-file>
</el-form-item>
<el-form-item label="电子签章" prop="dzqz">
<sc-upload v-model="dataForm.dzqz" title="电子签章"></sc-upload>
</el-form-item>
</el-form>
</el-main>
</el-aside>
<el-main >
<div ref="container" class="docx"></div>
</el-main>
<el-aside width="250px">
<div class="header">可用的合同参数</div>
<el-table :data="params" style="width: 100%;" border size="small" stripe highlightCurrentRow>
<el-table-column prop="name" label="参数名称" align="left" ></el-table-column>
<el-table-column prop="param" label="参数" align="left" ></el-table-column>
</el-table>
</el-aside>
</el-container>
</template>
let container = ref();
const handleChange: UploadProps['onChange'] = (file: any) => {
fileViews.value = file
renderAsync(fileViews.value.raw, container.value, undefined, {
className: "docx", // 默认和文档样式类的类名/前缀
inWrapper: true, // 启用围绕文档内容渲染包装器
ignoreWidth: false, // 禁止页面渲染宽度
ignoreHeight: false, // 禁止页面渲染高度
ignoreFonts: false, // 禁止字体渲染
breakPages: true, // 在分页符上启用分页
ignoreLastRenderedPageBreak: true, //禁用lastRenderedPageBreak元素的分页
experimental: false, //启用实验性功能(制表符停止计算)
trimXmlDeclaration: true, //如果为真,xml声明将在解析之前从xml文档中删除
debug: false, // 启用额外的日志记录
})
}
这个效果就比较好
接下来的问题,上面的代码是在文件上传的时候,直接预览word,保存之后,通过再打开这个合同模板,又是怎么加载出来呢?从下图可以看到word那部分是空白的。
const preview = (url) => {
let xhr = new XMLHttpRequest();
xhr.open("get", url, true);
xhr.responseType = "blob";
xhr.onload = function () {
if (this.status === 200) {
renderAsync(xhr.response, dzhtRef.value);
}
};
xhr.send();
}
async function load(val:string){
const res = await proxy.$api.contract.psiContractTpl.load({id:val,asId:userInfo.value.currentAsId});
if (res.success) {
if (res.data){
dataForm.value = res.data;
nextTick(()=>{
preview(dataForm.value.htFilePath);
})
}
} else {
proxy.$message.error(res.msg);
}
}
这样就出来了