|
@@ -208,7 +208,8 @@
|
|
|
</el-button>
|
|
|
<template #dropdown>
|
|
|
<el-dropdown-menu>
|
|
|
- <el-dropdown-item command="word">Word格式</el-dropdown-item>
|
|
|
+ <el-dropdown-item command="word">Word格式</el-dropdown-item
|
|
|
+ ><!-- word -->
|
|
|
<el-dropdown-item command="pdf">PDF格式</el-dropdown-item>
|
|
|
<!-- <el-dropdown-item command="pdf-to-word"
|
|
|
>PDF转Word</el-dropdown-item
|
|
@@ -284,6 +285,8 @@ import elDragDialog from "@/directive/el-drag-dialog";
|
|
|
import axios from "axios";
|
|
|
import jsPDF from "jspdf";
|
|
|
import html2canvas from "html2canvas";
|
|
|
+import htmlDocx from "html-docx-js/dist/html-docx"; // 需要先安装: npm install html-docx-js
|
|
|
+import { saveAs } from "file-saver"; // 需要先安装: npm install file-saver
|
|
|
|
|
|
export default {
|
|
|
components: {
|
|
@@ -409,8 +412,132 @@ export default {
|
|
|
this.$message.error("PDF转Word失败,请稍后重试");
|
|
|
}
|
|
|
},
|
|
|
+ // 2. 替换原有的 exportDocument 方法
|
|
|
+ async exportDocument(template) {
|
|
|
+ try {
|
|
|
+ const templateData = JSON.parse(template.data || "[]");
|
|
|
+
|
|
|
+ // 创建文档内容
|
|
|
+ let contentData = `
|
|
|
+ <!DOCTYPE html>
|
|
|
+ <html>
|
|
|
+ <head>
|
|
|
+ <meta charset="UTF-8">
|
|
|
+ <style>
|
|
|
+ /* 保持现有样式 */
|
|
|
+ body {
|
|
|
+ font-family: SimSun, serif;
|
|
|
+ font-size: 12pt;
|
|
|
+ line-height: 1.5;
|
|
|
+ }
|
|
|
+ table {
|
|
|
+ width: 100%;
|
|
|
+ border-collapse: collapse;
|
|
|
+ margin: 8px 0;
|
|
|
+ }
|
|
|
+ td, th {
|
|
|
+ border: 1px solid black;
|
|
|
+ padding: 8px;
|
|
|
+ min-height: 18px;
|
|
|
+ }
|
|
|
+ p {
|
|
|
+ margin: 6px 0;
|
|
|
+ }
|
|
|
+ .template-textarea {
|
|
|
+ page-break-after: always;
|
|
|
+ }
|
|
|
+ img {
|
|
|
+ max-width: 100%;
|
|
|
+ height: auto;
|
|
|
+ display: block;
|
|
|
+ margin: 10px auto;
|
|
|
+ }
|
|
|
+ </style>
|
|
|
+ </head>
|
|
|
+ <body>`;
|
|
|
+
|
|
|
+ // 处理每个模版段落
|
|
|
+ for (const item of templateData) {
|
|
|
+ const tempDiv = document.createElement("div");
|
|
|
+ tempDiv.innerHTML = item.content;
|
|
|
+
|
|
|
+ // 处理图片
|
|
|
+ const images = tempDiv.getElementsByTagName("img");
|
|
|
+ for (const img of Array.from(images)) {
|
|
|
+ try {
|
|
|
+ // 如果图片已经是 base64 格式,直接使用
|
|
|
+ if (img.src.startsWith("data:image")) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 如果是URL,转换为base64
|
|
|
+ const response = await fetch(img.src);
|
|
|
+ const blob = await response.blob();
|
|
|
+ const base64 = await new Promise((resolve) => {
|
|
|
+ const reader = new FileReader();
|
|
|
+ reader.onloadend = () => resolve(reader.result);
|
|
|
+ reader.readAsDataURL(blob);
|
|
|
+ });
|
|
|
+ img.src = base64;
|
|
|
+ } catch (error) {
|
|
|
+ console.error("处理图片失败:", error);
|
|
|
+ // 如果转换失败,保留原始src
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 处理表格样式
|
|
|
+ const tables = tempDiv.getElementsByTagName("table");
|
|
|
+ Array.from(tables).forEach((table) => {
|
|
|
+ table.setAttribute("border", "1");
|
|
|
+ table.style.borderCollapse = "collapse";
|
|
|
+
|
|
|
+ const cells = table.getElementsByTagName("td");
|
|
|
+ Array.from(cells).forEach((cell) => {
|
|
|
+ cell.style.border = "1px solid black";
|
|
|
+ cell.style.padding = "8px";
|
|
|
+ });
|
|
|
+ });
|
|
|
+
|
|
|
+ // 处理文本样式
|
|
|
+ const textElements = tempDiv.getElementsByTagName("span");
|
|
|
+ Array.from(textElements).forEach((span) => {
|
|
|
+ const style = window.getComputedStyle(span);
|
|
|
+ span.style.color = style.color;
|
|
|
+ span.style.fontSize = style.fontSize;
|
|
|
+ span.style.fontWeight = style.fontWeight;
|
|
|
+ });
|
|
|
+
|
|
|
+ contentData += `
|
|
|
+ <div class="template-textarea">
|
|
|
+ ${tempDiv.innerHTML}
|
|
|
+ </div>`;
|
|
|
+ }
|
|
|
+
|
|
|
+ contentData += `
|
|
|
+ </body>
|
|
|
+ </html>`;
|
|
|
+
|
|
|
+ // 转换为 Word 文档
|
|
|
+ const converted = htmlDocx.asBlob(contentData, {
|
|
|
+ orientation: "portrait",
|
|
|
+ margins: {
|
|
|
+ top: "2.54cm",
|
|
|
+ right: "2.54cm",
|
|
|
+ bottom: "2.54cm",
|
|
|
+ left: "2.54cm",
|
|
|
+ },
|
|
|
+ });
|
|
|
+
|
|
|
+ // 下载文件
|
|
|
+ saveAs(converted, `${template.title}.docx`);
|
|
|
+ this.$message.success("导出成功");
|
|
|
+ } catch (error) {
|
|
|
+ console.error("导出Word文档失败:", error);
|
|
|
+ this.$message.error("导出文档失败,请稍后重试");
|
|
|
+ }
|
|
|
+ },
|
|
|
|
|
|
- // 修改导出文档的方法,确保表格有边框
|
|
|
+ /* // 修改导出文档的方法,确保表格有边框
|
|
|
async exportDocument(template) {
|
|
|
try {
|
|
|
const templateData = JSON.parse(template.data || "[]");
|
|
@@ -450,6 +577,17 @@ export default {
|
|
|
if (textAlign && textAlign !== "left") {
|
|
|
element.style.textAlign = textAlign;
|
|
|
}
|
|
|
+
|
|
|
+ // 处理表格边框
|
|
|
+ if (element.tagName === "TABLE") {
|
|
|
+ element.style.borderCollapse = "collapse";
|
|
|
+ element.style.width = "100%";
|
|
|
+ element.style.border = "10px solid windowtext";
|
|
|
+ element.style.msoTableLspace = "0pt";
|
|
|
+ element.style.msoTableRspace = "0pt";
|
|
|
+ element.style.msoBorderAlt = "solid windowtext.5pt";
|
|
|
+ element.style.msoPaddingAlt = "0cm 5.4pt 0cm 5.4pt";
|
|
|
+ }
|
|
|
};
|
|
|
|
|
|
const contentContainer = document.createElement("div");
|
|
@@ -466,29 +604,6 @@ export default {
|
|
|
const allElements = tempDiv.getElementsByTagName("*");
|
|
|
Array.from(allElements).forEach((element) => {
|
|
|
processStyles(element);
|
|
|
-
|
|
|
- // 特别处理表格
|
|
|
- if (element.tagName === "TABLE") {
|
|
|
- element.style.borderCollapse = "collapse";
|
|
|
- element.style.width = "100%";
|
|
|
- element.style.border = "1pt solid windowtext";
|
|
|
- element.style.msoTableLspace = "0pt";
|
|
|
- element.style.msoTableRspace = "0pt";
|
|
|
- element.style.msoBorderAlt = "solid windowtext .5pt";
|
|
|
- element.style.msoPaddingAlt = "0cm 5.4pt 0cm 5.4pt";
|
|
|
- }
|
|
|
-
|
|
|
- // 处理表格单元格
|
|
|
- if (element.tagName === "TD" || element.tagName === "TH") {
|
|
|
- element.style.border = "1pt solid windowtext";
|
|
|
- element.style.padding = "5pt";
|
|
|
- element.style.msoBorderAlt = "solid windowtext .5pt";
|
|
|
-
|
|
|
- if (element.tagName === "TH") {
|
|
|
- element.style.backgroundColor = "#f0f0f0";
|
|
|
- element.style.fontWeight = "bold";
|
|
|
- }
|
|
|
- }
|
|
|
});
|
|
|
|
|
|
templateSection.innerHTML = tempDiv.innerHTML;
|
|
@@ -532,34 +647,37 @@ export default {
|
|
|
</w:WordDocument>
|
|
|
</xml>
|
|
|
<style>
|
|
|
- /* 基础样式 */
|
|
|
+
|
|
|
body, div, table, td, p {
|
|
|
font-family: "SimSun", "宋体", serif;
|
|
|
font-size: 10.5pt;
|
|
|
line-height: 1.5;
|
|
|
}
|
|
|
|
|
|
- /* 表格样式 */
|
|
|
- table {
|
|
|
+
|
|
|
+ body table {
|
|
|
border-collapse: collapse;
|
|
|
width: 100%;
|
|
|
- mso-table-layout-alt: fixed;
|
|
|
+ border: 10pt solid windowtext;
|
|
|
+ mso-table-lspace: 0pt;
|
|
|
+ mso-table-rspace: 0pt;
|
|
|
+ mso-border-alt: solid windowtext.5pt;
|
|
|
mso-padding-alt: 0cm 5.4pt 0cm 5.4pt;
|
|
|
- border:1px solid #000 !important;
|
|
|
}
|
|
|
+
|
|
|
|
|
|
- /* 分页样式 */
|
|
|
- .template-textarea {
|
|
|
+
|
|
|
+ .template-textarea {
|
|
|
page-break-after: always;
|
|
|
}
|
|
|
|
|
|
- /* Word特定样式 */
|
|
|
+
|
|
|
@page {
|
|
|
mso-page-orientation: portrait;
|
|
|
margin: 1.0in;
|
|
|
}
|
|
|
|
|
|
- /* 确保中文正确显示 */
|
|
|
+
|
|
|
@font-face {
|
|
|
font-family: "SimSun";
|
|
|
panose-1: 2 1 6 0 3 1 1 1 1 1;
|
|
@@ -610,7 +728,7 @@ export default {
|
|
|
console.error("导出文档失败:", error);
|
|
|
this.$alert("导出文档时发生错误,请稍后重试。");
|
|
|
}
|
|
|
- },
|
|
|
+ }, */
|
|
|
/* 客户名称 */
|
|
|
getCusomName(phaseId) {
|
|
|
const product = this.customList.find((item) => item.id === phaseId);
|