方法一仅用 FileSaver 一个js
外部直接引入js:代码如下
let contentHtml = `
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.fu-title {
width: 100%
height: 5.31vw
line-height: 5.31vw
text-align: center
font-family: '宋体'
font-size: 36px
color: #fc3f3f
}
</style>
</head>
<body>
<div class="fu logHistoryManage_detail">
<div class="fu-title">日志报表信息</div>
<form class="fu-form">
<table border="0" cellspacing="0">
<tr height="30" border='solid 1px red' style='color:#888'>
<td width="610" align="left">${sendDepartName ? sendDepartName : "ohqwzfw"}</td>
<td width="610" align="center" ></td>
<td width="610" align="right">${sendUserName} </td>
</tr>
</table>
<hr style='color:red'/><br>
<div class="form-title" style="height: auto">${title}</div>
<div class="form-summary" style="word-wrap: break-word">
${content ? content : ''
}
</div>
<br>
<!-- 领导批示 -->
<div>
<h2>领导批示</h2>
<table border="1" cellspacing="0">
<tr height="50">
<td width="200" align="center">姓名</td>
<td width="600" align="center">批示内容</td>
<td width="200" align="center">批示时间</td>
</tr>
${leaderIdeaList.length>0?leaderIdeaList.map((item, index) =>{
return `
<tr height="100">
<td width="200" align="center">${item.optUserName}</td>
<td width="600" align="center">${item.remark ? item.remark : '暂无内容'}</td>
<td width="200" align="center">${item.createTime ? item.createTime : ''}</td>
</tr>
`
}):`<tr height="100">
<td width="200" align="center"></td>
<td width="600" align="center"></td>
<td width="200" align="center"></td>
</tr>`
}
</table>
</div>
</form>
</div>
</body>
</html>
`
//重要的代码就这两行----这里是项目中没有npm包管理外部直接引用的js
let blob = new Blob([contentHtml], { type: "application/mswordcharset=utf-8" })
saveAs(blob, "日志报表信息.docx")
复制
使用包管理安装 FileSaver
首先需要安装:fileSaver
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 (
`
<!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">上报信息</div>
<div class="formTitle_second">上报信息</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">地点定位:</span>
<span>${reportInfoDetail['locationAddress']}</span>
</div>
<div class="formContent_box display_flex" style="display:flex">
<span class="formContent_box_title">上报时间:</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">联系方式:</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">指派时间:</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:32vwjustify-content: space-between">
<div>
<span>签收单位:${itm['claimDepartmentName']}</span>
</div>
<div>
<span>签收时间:${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">上报信息</div>
<div class="formContent_box display_flex"
style="width:32vwjustify-content: space-between">
<div>
<span>上报单位:${itm['claimDepartmentName']}</span>
</div>
<div>
<span>上报时间:${itm['handleTime'] != null ? itm['handleTime'] : ''}</span>
</div>
</div>
<br/>
`
}) : '无数据'
}
</div >
<div class="fromBox">
<div class="formTitle_first">其他信息</div>
<div class="formContent_box display_flex">
<span class="formContent_box_title">信息状态:</span>
<span>
${list[eventState - 1].desc}
${reportInfoDetail?.finishTime != null ? reportInfoDetail?.finishTime : ''}
</span>
</div>
<div class="formContent_box display_flex">
<span class="formContent_box_title">采纳状态:</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/mswordcharset=utf-8" })
// let blob = htmlDocx.asBlob(html, { orientation: "landscape" })
FileSaver.saveAs(blob, "信息管理文件.doc")
}
export {
loadFile
}
复制
方法二:
两个js都需要引入,还需要引入jquery.js,最好1.8版本以上的
原理和那个差不多,只是理解起来比较简单,代码如下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<!-- 注意引入的顺序 -->
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/FileSaver.js/2.0.5/FileSaver.min.js"></script>
<script src='./jquery.wordexport.js'></script>
<style>
.word-export,.test {
display: block
padding: 10px
width: 80px
background-color: rgb(56, 131, 230)
}
</style>
<body>
<span class="word-export">导出word</span>
<div id="page-content2" style="display:flexjustify-content:space-between">
<div id="page-content">
jquery 测试
</div>
<div id="page-content1">
jquery 测试
</div>
</div>
<script type="text/javascript">
$(".word-export").click(function (event) {
// 打印节点就可以
$("#page-content2").wordExport("测试")
})
</script>
</body>
</html>
复制
解决的是导出含有echarts的页面为word文档,需要考虑echarts图表的大小,采用的是设置角度解析器来预设置图片宽高,也考虑到多图导出问题,下面是我的解决过程
建立一个word.js,内容如下
不知道模板文件如何导入或导入错误,JszipUtils.getBinaryContent(fileDocx, function(err, res) {})时,不知道这个fileDocx模板文件放在哪里,然后出现引入路径错误
Error: Can't find end of central directory : is this a zip file?
在使用vue-cli2时,我们需要把模板文件放到static目录下
在使用vue-cli3时,我们需要把模板文件放在public目录下
然后当config中的publicPath是'./'时,直接传入文件名就好,如
JszipUtils.getBinaryContent('template.docx', function(err, res) {})
当config中的publicPath是 ‘/’时,则需要../一层层到相应位置,要特别注意省去public目录,如
JszipUtils.getBinaryContent('../../template.docx', function(err, res) {})
我的环境是vue-cli3,然后再public目录下建立word文件夹存放模板文件weektmp.docx