js+html点击按钮实现word文档下载,自定义文档格式【附全部代码】
function handleWordExport() {
// 正在下载word文件中,请稍后...
showMessage('正在下载word文件中,请稍后...');
this.download('接口文档', data)
}
function showMessage(text) {
const messageBox = document.querySelector('.message-box');
messageBox.classList.add('active');
messageBox.innerHTML = `<p>${text}</p>`;
setTimeout(() => {
messageBox.classList.remove('active');
}, 3000); // 3秒后自动关闭提示框
}
/**
* 文档处理(World)
* Created by xiangshaolin on 2022/12/14.
*/
/**
* 生成Word文档
* @param content
* @return {string}
*/
function createWord(content) {
let wordContent = []
createWordHeader(wordContent)
createApiInfo(content, wordContent)
createWordFooter(wordContent)
return wordContent.join('\n')
}
/**
* 生成Word文档
* @param content
* @return {string}
*/
function createWordHeader(wordContent) {
let wordHeader = `<!DOCTYPE HTML PUBLIC "-// W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/>
<style type="text/css">
.doc-body {
width: 90%;
margin: 20px auto;
font-family:"宋体";
font-size: 16px;
}
.doc-row {
position: relative;
height: auto;
margin-right: 0;
margin-left: 0;
zoom: 1;
display: block;
box-sizing: border-box;
}
.doc-line {
height: 35px;
line-height:35px;
}
.doc-divider {
height: 1px;
background: #e8e8e8;
border-bottom: 1px solid #e8e8e8;
}
.doc-title {
font-weight: 600;
font-size: 18px;
margin-top: 15px;
border-left: 3px solid #00ab6d;
}
.doc-api {
margin-top: 10px;
margin-bottom: 20px;
}
.doc-content {
margin-top: 10px;
max-height: 30px;
}
.doc-code-editor {
border: #ccc 1px solid;
border-left-width: 4px;
background-color: #fefefe;
box-shadow: 0 0 4px #eee;
word-break: break-all;
word-wrap: break-word;
color: #444;
}
.doc-code-editor .string { color: green; } /*字符串的样式*/
.doc-code-editor .number { color: darkorange; } /*数字的样式*/
.doc-code-editor .boolean { color: blue; } /*布尔型数据的样式*/
.doc-code-editor .null { color: magenta; } /*null值的样式*/
.doc-code-editor .key { color: red; } /*key值的样式*/
.doc-method {
font-size: 14px;
font-weight: 600;
margin-right: 10px;
text-align: center;
border-radius: 3px;
text-shadow: 0 1px 0 rgba(0, 0, 0, 0.1);
}
.doc-table {
width: 120%;
border: 1px solid #c7c4c4;
border-collapse: collapse;
}
.doc-table tr {
border: 1px solid #c7c4c4;
height: 40px;
}
.doc-table th {
border: 1px solid #c7c4c4;
background-color: #dfdada;
}
.doc-table td {
border: 1px solid #c7c4c4;
}
</style>
</head>
<body>
<div class="doc-body">`
wordContent.push(wordHeader)
}
/**
* 生成Word结尾
* @param content
* @return {string}
*/
function createWordFooter(wordContent) {
wordContent.push('</div></body></html>')
}
/**
* 遍历tags分组信息
* @param {*} instance 当前分组实例对象
* @param {*} wordContent markdown文本集合对象
*/
function createApiInfo(apiContent, wordContent) {
if (apiContent !== undefined && apiContent != null) {
wordContent.push('\n')
wordContent.push('<h1>1.接口列表</h1>')
if(Array.isArray(apiContent) && apiContent.length) {
apiContent.forEach((api, index) => {
// let docIndex = parseInt(index) + 1
// let docParent = '2.' + docIndex
// let tagTitle = docParent +
// ('<h2>' + tagTitle + '</h2>');
wordLines(wordContent)
createWordApiInfo(api, wordContent)
})
}
}
}
/**
* 主动换行
* @param {*} wordContent
*/
function wordLines(wordContent) {
wordContent.push('\n')
}
/**
* 遍历接口详情
* @param {*} apiInfo 接口实例
* @param {*} wordContent markdown文本集合对象
*/
function createWordApiInfo(apiInfo, wordContent) {
// 二级标题
wordLines(wordContent)
wordContent.push('<div class="doc-api">')
wordContent.push('<div class="doc-title">接口名称</div>')
wordContent.push('<div class="doc-content">' + apiInfo.name + '</div>');
wordContent.push('<div class="doc-title">接口地址</div>')
wordContent.push('<div class="doc-content"><span class="doc-method">' + 'POST' + '</span> <code>' + apiInfo.url + '</code></div>');
wordContent.push('<div class="doc-title">接口描述</div>')
wordContent.push('<div class="doc-content">' + apiInfo.remark + '</div>')
// ('<div class="doc-title">请求数据类型</div>')
// ('<div class="doc-content"><code>' + apiInfo + '</code></div>')
//
// ('<div class="doc-title">响应数据类型</div>')
// ('<div class="doc-content"><code>' + apiInfo + '</code></div>')
// 请求参数
if(apiInfo.model) {
createWordApiRequestParameters(apiInfo, wordContent)
}
wordContent.push('</div>');
}
/**
* 请求参数
* @param {*} apiInfo
* @param {*} wordContent
*/
function createWordApiRequestParameters(apiInfo, wordContent) {
let reqParameters = apiInfo.model.fields
wordLines(wordContent)
wordContent.push('<div class="doc-title">请求参数</div><br/>')
wordContent.push('<div class="doc-content">')
wordContent.push('<table class="doc-table">')
// 表头
wordContent.push('<thead><tr><th>参数名称</th><th>参数说明</th><th>请求类型</th><th>必须</th><th>数据类型</th><th>schema</th></tr></thead>')
wordContent.push('<tbody>')
// 判断是否拥有请求参数
if (reqParameters.length > 0) {
// if ( > 0) {
// 级联表格,在表格需要最佳空格缩进符号
createParameterTable(reqParameters, wordContent, 1)
} else {
// 无参数
wordContent.push('<tr><td colspan="6">暂无</td></tr>')
}
wordContent.push('</tbody>')
wordContent.push('</table>')
wordContent.push('</div>')
}
/**
* 递归循环遍历参数得到markdown表格
* @param {*} parameters
* @param {*} wordContent
*/
function createParameterTable(parameters, wordContent) {
if (parameters != null && parameters != undefined && parameters.length > 0) {
parameters.forEach((param, index) => {
wordContent.push('<tr>')
wordContent.push('<td>' + param.name + '</td>')
wordContent.push('<td>' + param.label + '</td>')
wordContent.push('<td>' + '</td>')
wordContent.push('<td>' + '</td>')
// ('<td>' + + '</td>')
wordContent.push('<td>' + param.clazz + '</td>')
wordContent.push('<td>' + '</td>')
wordContent.push('</tr>')
})
}
}
/**
* 下载Word文档
* @param fileName
* @param content
*/
function download(fileName, content) {
content = createWord(content)
let a = document.createElement('a')
const url = window.URL.createObjectURL(
new Blob([content], {
type: 'application/msword;charset=utf-8'
})
)
a.href = url
a.download = fileName
a.click()
window.URL.revokeObjectURL(url)
}
var data = [
{
"interfaceId": "blockStockBox",
"interfaceName": "冻结或解冻箱库存",
"interfaceType": "relative",
"url": "/3c/box/blockStockBox",
"option": "{\"recordFlag\":true,\"limitFlag\":false,\"limitRate\":5,\"headers\":[]}",
"example": "",
"flowId": "blockOrUnBlockStockBoxes",
"status": 1,
"persist": 0,
"remark": "",
"createTime": "2024-05-10 21:16:10",
"createUser": "",
"updateTime": null,
"updateUser": null,
"flowName": null,
"tags": null,
"realUrl": "/api/flow/3c/box/blockStockBox",
"absolute": false
},
{
"interfaceId": "getIntoTraceDetail",
"interfaceName": "按跟踪号获取箱入库单信息",
"interfaceType": "relative",
"url": "/3c/getIntoTraceDetail",
"option": "{\"recordFlag\":true,\"limitFlag\":false,\"limitRate\":5,\"headers\":[]}",
"example": "",
"flowId": "getIntoTraceDetail",
"status": 1,
"persist": 0,
"remark": "",
"createTime": "2024-04-28 16:40:20",
"createUser": "",
"updateTime": null,
"updateUser": null,
"flowName": null,
"tags": null,
"realUrl": "/api/flow/3c/getIntoTraceDetail",
"absolute": false
}
]