From 592c1750b148874737cdfba4b22b6229f9805fe6 Mon Sep 17 00:00:00 2001 From: zhouwx <1175765986@qq.com> Date: 星期三, 02 七月 2025 14:55:27 +0800 Subject: [PATCH] 新增 --- src/views/build/conpanyFunctionConsult/digitalFileDep/manageType/qualityManual/components/exportDoc.js | 138 ++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 138 insertions(+), 0 deletions(-) diff --git a/src/views/build/conpanyFunctionConsult/digitalFileDep/manageType/qualityManual/components/exportDoc.js b/src/views/build/conpanyFunctionConsult/digitalFileDep/manageType/qualityManual/components/exportDoc.js new file mode 100644 index 0000000..d29dd2f --- /dev/null +++ b/src/views/build/conpanyFunctionConsult/digitalFileDep/manageType/qualityManual/components/exportDoc.js @@ -0,0 +1,138 @@ +// 引入工具 +import PizZip from 'pizzip'; +import Docxtemplater from 'docxtemplater'; +import JSZipUtils from 'jszip-utils'; +import { saveAs } from 'file-saver'; + +// 加载 .docx 模板文件 +function loadFile(url, callback) { + JSZipUtils.getBinaryContent(url, callback); +} + +// 下载生成的文档 +export function download(file, name) { + saveAs(file, name); +} + +// 处理富文本,提取段落和缩进信息 +function processRichText(html) { + if (!html) return ''; + + // 将HTML字符串转换为DOM对象 + const parser = new DOMParser(); + const doc = parser.parseFromString(html, 'text/html'); + + let result = []; + + // 处理普通段落 + const paragraphs = doc.querySelectorAll('p'); + paragraphs.forEach(p => { + const style = p.getAttribute('style') || ''; + const indentMatch = style.match(/text-indent:\s*(\d+)pt/); + const indent = indentMatch ? parseInt(indentMatch[1]) / 24 : 0; + const text = p.textContent.trim(); + + if (text) { + const indentStr = indent > 0 ? ' '.repeat(indent) : ''; + result.push(indentStr + text); + } + }); + + // 处理列表(ul/li) + const lists = doc.querySelectorAll('ul'); + lists.forEach(ul => { + const lis = ul.querySelectorAll('li'); + lis.forEach(li => { + // 计算缩进层级 + let parent = li.parentElement; + let indentLevel = 0; + while (parent && parent !== ul) { + if (parent.tagName === 'UL') indentLevel++; + parent = parent.parentElement; + } + + const text = li.textContent.trim(); + if (text) { + // 使用不同符号表示不同层级 + const bullets = ['▪', '•', '▫', '◦']; + const bullet = bullets[Math.min(indentLevel, bullets.length - 1)]; + const indentStr = ' '.repeat(indentLevel); + result.push(indentStr + bullet + ' ' + text); + } + }); + }); + + return result.join('\n\n'); // 用两个换行符分隔段落 +} + +function convertTreeToHtml(data) { + let html = ''; + + function buildList(items) { + let listHtml = '<ul style="font-family: 宋体; font-size: 12pt; line-height: 1.5;">'; + + items.forEach(item => { + listHtml += `<li style="margin-bottom: 6pt;">${item.label}`; + + if (item.children && item.children.length > 0) { + listHtml += buildList(item.children); + } + + listHtml += '</li>'; + }); + + listHtml += '</ul>'; + return listHtml; + } + + html = buildList(data); + return html; +} + +// 生成并下载 Word 文档 +export function generateWordDocument(templatePath, data, name) { + // 处理富文本字段(如果有) + if (data.summaries && typeof data.summaries === 'string') { + data.summaries = processRichText(data.summaries); + } + if (data.policies && typeof data.policies === 'string') { + data.policies = processRichText(data.policies); + } + + // 处理树形结构数据(如果有) + if (data.deptList && Array.isArray(data.deptList)) { + data.departmentsHtml = processRichText(convertTreeToHtml(data.deptList)); + } + + loadFile(templatePath, function (error, content) { + if (error) { + throw error; + } + + try { + // 加载模板文件内容到 PizZip + const zip = new PizZip(content); + const doc = new Docxtemplater(zip, { + paragraphLoop: true, + linebreaks: true, + }); + + // 设置模板中的占位符数据 + doc.setData(data); + + // 渲染文档 + doc.render(); + + // 生成最终的文档 Blob + const fileWord = doc.getZip().generate({ + type: 'blob', + mimeType: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', + }); + + saveAs(fileWord, name); + } catch (error) { + console.error('Error rendering document:', error); + throw error; + } + }); +} \ No newline at end of file -- Gitblit v1.9.2