|
@@ -180,7 +180,7 @@
|
|
|
v-el-drag-dialog
|
|
|
width="50%"
|
|
|
append-to-body
|
|
|
- :close-on-click-modal="false"
|
|
|
+ :close-on-click-modal="false"
|
|
|
>
|
|
|
<el-table
|
|
|
:data="boundTemplateList"
|
|
@@ -278,6 +278,7 @@ import {
|
|
|
updateDocument,
|
|
|
exportDocument,
|
|
|
exportToPDF,
|
|
|
+ htmlWordNew,
|
|
|
} from "@/api/document";
|
|
|
import { searchCustomer } from "@/api/customer";
|
|
|
import { searchProduct } from "@/api/product";
|
|
@@ -415,11 +416,56 @@ export default {
|
|
|
}
|
|
|
},
|
|
|
// 2. 替换原有的 exportDocument 方法
|
|
|
- /* async exportDocument(template) {
|
|
|
+ async exportDocument(template) {
|
|
|
try {
|
|
|
const templateData = JSON.parse(template.data || "[]");
|
|
|
|
|
|
- // 创建文档内容
|
|
|
+ // 创建一个临时的容器来存放内容
|
|
|
+ const contentContainer = document.createElement("div");
|
|
|
+ contentContainer.className = "content";
|
|
|
+
|
|
|
+ // 处理每个模版段落
|
|
|
+ templateData.forEach((item) => {
|
|
|
+ const templateSection = document.createElement("div");
|
|
|
+ templateSection.className = "template-textarea";
|
|
|
+
|
|
|
+ // 创建临时div用于处理HTML内容
|
|
|
+ const tempDiv = document.createElement("div");
|
|
|
+ tempDiv.innerHTML = item.content;
|
|
|
+ // 处理所有表格
|
|
|
+ tempDiv.querySelectorAll("table").forEach(table => {
|
|
|
+ // 检查表格及其单元格是否有任何边框
|
|
|
+ const tableStyle = table.getAttribute("style");
|
|
|
+
|
|
|
+ // 如果表格没有style属性,直接判定为无边框
|
|
|
+ if (!tableStyle) {
|
|
|
+ table.setAttribute("data-code", "noactive");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 检查所有单元格
|
|
|
+ const cells = Array.from(table.querySelectorAll("td, th"));
|
|
|
+ const hasBorder = cells.some(cell => {
|
|
|
+ const cellStyle = cell.getAttribute("style");
|
|
|
+ // 如果单元格没有style属性,视为无边框
|
|
|
+ if (!cellStyle) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ // 检查是否存在任何边框相关的样式
|
|
|
+ return /border(?:-(top|right|bottom|left))?:\s*[^;]*[1-9]/.test(cellStyle);
|
|
|
+ });
|
|
|
+
|
|
|
+ if (hasBorder) {
|
|
|
+ table.setAttribute("data-code", "active");
|
|
|
+ // 保持原有样式
|
|
|
+ } else {
|
|
|
+ table.setAttribute("data-code", "noactive");
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ templateSection.innerHTML = tempDiv.innerHTML;
|
|
|
+ contentContainer.appendChild(templateSection);
|
|
|
+ });
|
|
|
let contentData = `
|
|
|
<!DOCTYPE html>
|
|
|
<html>
|
|
@@ -427,334 +473,52 @@ export default {
|
|
|
<meta charset="UTF-8">
|
|
|
<style>
|
|
|
body {
|
|
|
- font-family: SimSun, serif; // 用宋体作默认字体
|
|
|
+ font-family: SimSun, serif;
|
|
|
font-size: 12pt;
|
|
|
line-height: 1.5;
|
|
|
- margin: 0;
|
|
|
- padding: 0;
|
|
|
}
|
|
|
- table {
|
|
|
- width: 100%;
|
|
|
+
|
|
|
+ /* 有边框的表格样式 */
|
|
|
+ table[data-code="active"] {
|
|
|
border-collapse: collapse;
|
|
|
- margin: 8px 0;
|
|
|
- table-layout: fixed;
|
|
|
+ width: 100%;
|
|
|
}
|
|
|
- td, th {
|
|
|
+ table[data-code="active"] td,
|
|
|
+ table[data-code="active"] th {
|
|
|
border: 1px solid black;
|
|
|
padding: 8px;
|
|
|
- word-wrap: break-word;
|
|
|
- min-height: 18px;
|
|
|
- }
|
|
|
- p {
|
|
|
- margin: 6px 0;
|
|
|
- }
|
|
|
- .template-textarea {
|
|
|
- page-break-after: always;
|
|
|
- margin: 0;
|
|
|
- padding: 0;
|
|
|
- }
|
|
|
- img {
|
|
|
- max-width: 100%;
|
|
|
- height: auto;
|
|
|
- display: block;
|
|
|
- margin: 10px auto;
|
|
|
}
|
|
|
-
|
|
|
- span, div, p {
|
|
|
- font-family: inherit;
|
|
|
- }
|
|
|
-
|
|
|
- table[border="1"] {
|
|
|
- border: 1px solid black;
|
|
|
+
|
|
|
+ /* 无边框的表格样式 */
|
|
|
+ table[data-code="noactive"] {
|
|
|
+ border: none;
|
|
|
+ border-collapse: collapse;
|
|
|
+ width: 100%;
|
|
|
}
|
|
|
-
|
|
|
- ul, ol {
|
|
|
- margin: 8px 0;
|
|
|
- padding-left: 20px;
|
|
|
+ table[data-code="noactive"] td,
|
|
|
+ table[data-code="noactive"] th {
|
|
|
+ border: none;
|
|
|
+ padding: 8px;
|
|
|
}
|
|
|
|
|
|
- h1, h2, h3, h4, h5, h6 {
|
|
|
- font-family: SimSun, serif;
|
|
|
- margin: 12px 0;
|
|
|
+ .template-textarea {
|
|
|
+ page-break-after: always;
|
|
|
}
|
|
|
</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)) {
|
|
|
- if (!img.src.startsWith("data:image")) {
|
|
|
- try {
|
|
|
- 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);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // 处理表格样式
|
|
|
- const tables = tempDiv.getElementsByTagName("table");
|
|
|
- Array.from(tables).forEach((table) => {
|
|
|
- // 只有当表格有边框属性时才添加边框样式
|
|
|
- if (table.getAttribute("border") ||
|
|
|
- window.getComputedStyle(table).border !== "none") {
|
|
|
- table.setAttribute("border", "1");
|
|
|
- table.style.borderCollapse = "collapse";
|
|
|
- table.style.width = "100%";
|
|
|
- table.style.tableLayout = "fixed";
|
|
|
-
|
|
|
- const cells = table.getElementsByTagName("td");
|
|
|
- Array.from(cells).forEach((cell) => {
|
|
|
- cell.style.border = "1px solid black";
|
|
|
- cell.style.padding = "8px";
|
|
|
- cell.style.wordWrap = "break-word";
|
|
|
- });
|
|
|
- }
|
|
|
- });
|
|
|
-
|
|
|
- // 保持原有样式
|
|
|
- const elements = tempDiv.getElementsByTagName("*");
|
|
|
- Array.from(elements).forEach((el) => {
|
|
|
- const computedStyle = window.getComputedStyle(el);
|
|
|
- const importantStyles = [
|
|
|
- "color",
|
|
|
- "background-color",
|
|
|
- "font-size",
|
|
|
- "font-weight",
|
|
|
- "text-align",
|
|
|
- "text-decoration",
|
|
|
- "font-style",
|
|
|
- "line-height",
|
|
|
- "margin",
|
|
|
- "padding"
|
|
|
- ];
|
|
|
-
|
|
|
- importantStyles.forEach((style) => {
|
|
|
- const value = computedStyle.getPropertyValue(style);
|
|
|
- if (value && value !== "initial") {
|
|
|
- el.style[style] = value;
|
|
|
- }
|
|
|
- });
|
|
|
- });
|
|
|
-
|
|
|
- contentData += `
|
|
|
- <div class="template-textarea">
|
|
|
- ${tempDiv.innerHTML}
|
|
|
- </div>`;
|
|
|
- }
|
|
|
-
|
|
|
- contentData += `
|
|
|
+ <body>
|
|
|
+ ${contentContainer.innerHTML}
|
|
|
</body>
|
|
|
</html>`;
|
|
|
|
|
|
- // 转换为 Word 文档
|
|
|
- const converted = htmlDocx.asBlob(contentData, {
|
|
|
- orientation: "portrait",
|
|
|
- margins: {
|
|
|
- top: "2.54cm",
|
|
|
- right: "2.54cm",
|
|
|
- bottom: "2.54cm",
|
|
|
- left: "2.54cm"
|
|
|
- },
|
|
|
- font: {
|
|
|
- name: "SimSun",
|
|
|
- size: "12pt"
|
|
|
- }
|
|
|
- });
|
|
|
-
|
|
|
- // 下载文件
|
|
|
- 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 || "[]");
|
|
|
-
|
|
|
- // 创建一个处理样式的函数
|
|
|
- const processStyles = (element) => {
|
|
|
- // 保留原有的样式
|
|
|
- const originalStyle = element.getAttribute("style") || "";
|
|
|
-
|
|
|
- // 处理字体颜色
|
|
|
- const color = window.getComputedStyle(element).color;
|
|
|
- if (color && color !== "rgb(0, 0, 0)") {
|
|
|
- element.style.color = color;
|
|
|
- }
|
|
|
-
|
|
|
- // 处理字体大小
|
|
|
- const fontSize = window.getComputedStyle(element).fontSize;
|
|
|
- if (fontSize && fontSize !== "16px") {
|
|
|
- element.style.fontSize = fontSize;
|
|
|
- }
|
|
|
-
|
|
|
- // 处理字体粗细
|
|
|
- const fontWeight = window.getComputedStyle(element).fontWeight;
|
|
|
- if (fontWeight && fontWeight !== "normal") {
|
|
|
- element.style.fontWeight = fontWeight;
|
|
|
- }
|
|
|
-
|
|
|
- // 处理背景色
|
|
|
- const backgroundColor =
|
|
|
- window.getComputedStyle(element).backgroundColor;
|
|
|
- if (backgroundColor && backgroundColor !== "transparent") {
|
|
|
- element.style.backgroundColor = backgroundColor;
|
|
|
- }
|
|
|
-
|
|
|
- // 处理对齐方式
|
|
|
- const textAlign = window.getComputedStyle(element).textAlign;
|
|
|
- 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");
|
|
|
- contentContainer.className = "content";
|
|
|
-
|
|
|
- templateData.forEach((item, index) => {
|
|
|
- const templateSection = document.createElement("div");
|
|
|
- templateSection.className = "template-textarea";
|
|
|
-
|
|
|
- const tempDiv = document.createElement("div");
|
|
|
- tempDiv.innerHTML = item.content;
|
|
|
-
|
|
|
- // 处理所有元素的样式
|
|
|
- const allElements = tempDiv.getElementsByTagName("*");
|
|
|
- Array.from(allElements).forEach((element) => {
|
|
|
- processStyles(element);
|
|
|
- });
|
|
|
-
|
|
|
- templateSection.innerHTML = tempDiv.innerHTML;
|
|
|
- contentContainer.appendChild(templateSection);
|
|
|
- });
|
|
|
-
|
|
|
- let contentData = `
|
|
|
- <!DOCTYPE html>
|
|
|
- <html xmlns:o='urn:schemas-microsoft-com:office:office'
|
|
|
- xmlns:w='urn:schemas-microsoft-com:office:word'
|
|
|
- xmlns:v='urn:schemas-microsoft-com:vml'
|
|
|
- xmlns='http://www.w3.org/TR/REC-html40'>
|
|
|
- <head>
|
|
|
- <meta charset="UTF-8">
|
|
|
- <xml>
|
|
|
- <w:WordDocument>
|
|
|
- <w:View>Print</w:View>
|
|
|
- <w:Zoom>100</w:Zoom>
|
|
|
- <w:DoNotOptimizeForBrowser/>
|
|
|
- <w:TrackMoves>false</w:TrackMoves>
|
|
|
- <w:TrackFormatting/>
|
|
|
- <w:ValidateAgainstSchemas/>
|
|
|
- <w:SaveIfXMLInvalid>false</w:SaveIfXMLInvalid>
|
|
|
- <w:IgnoreMixedContent>false</w:IgnoreMixedContent>
|
|
|
- <w:AlwaysShowPlaceholderText>false</w:AlwaysShowPlaceholderText>
|
|
|
- <w:DoNotPromoteQF/>
|
|
|
- <w:LidThemeOther>EN-US</w:LidThemeOther>
|
|
|
- <w:LidThemeAsian>ZH-CN</w:LidThemeAsian>
|
|
|
- <w:LidThemeComplexScript>X-NONE</w:LidThemeComplexScript>
|
|
|
- <w:Compatibility>
|
|
|
- <w:BreakWrappedTables/>
|
|
|
- <w:SnapToGridInCell/>
|
|
|
- <w:WrapTextWithPunct/>
|
|
|
- <w:UseAsianBreakRules/>
|
|
|
- <w:DontGrowAutofit/>
|
|
|
- <w:SplitPgBreakAndParaMark/>
|
|
|
- <w:EnableOpenTypeKerning/>
|
|
|
- <w:DontFlipMirrorIndents/>
|
|
|
- <w:OverrideTableStyleHps/>
|
|
|
- </w:Compatibility>
|
|
|
- </w:WordDocument>
|
|
|
- </xml>
|
|
|
- <style>
|
|
|
-
|
|
|
- body, div, table, td, p {
|
|
|
- font-family: "SimSun", "宋体", serif;
|
|
|
- font-size: 10.5pt;
|
|
|
- line-height: 1.5;
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- body table {
|
|
|
- border-collapse: collapse;
|
|
|
- width: 100%;
|
|
|
- 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;
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- .template-textarea {
|
|
|
- page-break-after: always;
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- @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;
|
|
|
- mso-font-alt: SimSun;
|
|
|
- mso-font-charset: 134;
|
|
|
- mso-generic-font-family: auto;
|
|
|
- mso-font-pitch: variable;
|
|
|
- mso-font-signature: 3 680460288 22 0 262145 0;
|
|
|
- }
|
|
|
- </style>
|
|
|
- </head>
|
|
|
- <body>
|
|
|
- ${contentContainer.innerHTML}
|
|
|
- </body>
|
|
|
- </html>`;
|
|
|
-
|
|
|
- const res = await exportDocument({
|
|
|
+ // 调用导出接口
|
|
|
+ const res = await htmlWordNew({
|
|
|
content: contentData,
|
|
|
title: template.title,
|
|
|
options: {
|
|
|
format: "docx",
|
|
|
encoding: "utf-8",
|
|
|
preserveStyles: true,
|
|
|
- pageOrientation: "portrait",
|
|
|
- margins: {
|
|
|
- top: "2.54cm",
|
|
|
- right: "2.54cm",
|
|
|
- bottom: "2.54cm",
|
|
|
- left: "2.54cm",
|
|
|
- },
|
|
|
},
|
|
|
});
|
|
|
|
|
@@ -763,6 +527,7 @@ export default {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
+ // 处理文件下载
|
|
|
const link = document.createElement("a");
|
|
|
link.href = res.data.file_path;
|
|
|
link.download = `${template.title}.docx`;
|
|
@@ -772,7 +537,7 @@ export default {
|
|
|
|
|
|
this.$message.success("导出成功");
|
|
|
} catch (error) {
|
|
|
- console.error("导出文档失败:", error);
|
|
|
+ console.error("导出Word文档失败:", error);
|
|
|
this.$alert("导出文档时发生错误,请稍后重试。");
|
|
|
}
|
|
|
},
|
|
@@ -820,7 +585,7 @@ export default {
|
|
|
const status = this.getstatusList.find((item) => item.value === statusId);
|
|
|
if (!status) return "info";
|
|
|
|
|
|
- // 根据状态值返回对应的类型
|
|
|
+ // 根据状值返回对应的类型
|
|
|
switch (status.value) {
|
|
|
case 5:
|
|
|
return "success";
|
|
@@ -983,7 +748,7 @@ export default {
|
|
|
|
|
|
// 调试用:打印每个匹配的详细信息
|
|
|
this.matchResults.forEach((match) => {
|
|
|
- // 据括号类型选��不同的切片方式
|
|
|
+ // 据括号类型选不同的切片方式
|
|
|
const content = match.startsWith("【")
|
|
|
? match.slice(1, -1)
|
|
|
: match.slice(1, -1);
|
|
@@ -1149,7 +914,7 @@ export default {
|
|
|
const replacementContent =
|
|
|
response.data.data.matched_data[0]?.content;
|
|
|
if (replacementContent) {
|
|
|
- // 处���富文本内容
|
|
|
+ // 处富文本内容
|
|
|
this.TemList.forEach((el, index) => {
|
|
|
console.log(el, originalMatch, replacementContent);
|
|
|
const processedContent = this.processTableContent(
|
|
@@ -1192,7 +957,7 @@ export default {
|
|
|
async replaceAll() {
|
|
|
this.batchReplaceLoading = true;
|
|
|
try {
|
|
|
- // 收��所有匹配
|
|
|
+ // 收所有匹配
|
|
|
const allLocations = this.matchResults.map((item) => {
|
|
|
return item.replace(/[\[\]【】]/g, "");
|
|
|
});
|
|
@@ -1239,7 +1004,7 @@ export default {
|
|
|
|
|
|
// 遍历所有替换内容和对应匹配项
|
|
|
this.matchResults.forEach((item) => {
|
|
|
- // 提取编号的函数只需定义一次
|
|
|
+ // 提取编号的函数只需定义一
|
|
|
const getCodeFromItem = (searchItem) => {
|
|
|
const cleanItem = searchItem.replace(/[\[\]【】]/g, "");
|
|
|
const match = cleanItem.match(/([A-Z0-9]+-[A-Z]+-\d+-\d+)/);
|
|
@@ -1349,7 +1114,7 @@ export default {
|
|
|
// 先获取纯文本内容用于匹配
|
|
|
const plainText = processNode(tempDiv);
|
|
|
|
|
|
- // 构建用于匹配分割标记的正则表达式
|
|
|
+ // 构建用于匹配分割标记��正则表达式
|
|
|
const splitRegex = new RegExp(
|
|
|
`(\\[|【)(.*?)(${searchCode})(.*?)(\\]|】)`,
|
|
|
"g"
|
|
@@ -1471,7 +1236,7 @@ export default {
|
|
|
}
|
|
|
);
|
|
|
|
|
|
- // 保持原有的图片和文本处理逻辑不变
|
|
|
+ // 保持原���的图片和文本处理逻辑不变
|
|
|
html = html.replace(
|
|
|
/\[图片:(.*?)\|style=(.*?)\|class=(.*?)\]/g,
|
|
|
(match, src, style, className) => {
|
|
@@ -1511,7 +1276,7 @@ export default {
|
|
|
this.templateQueryForm.page = page;
|
|
|
this.loadTemplateList();
|
|
|
},
|
|
|
- // 加载模版列表
|
|
|
+ // 加载模版���表
|
|
|
loadTemplateList() {
|
|
|
this.templateLoading = true;
|
|
|
searchList(this.templateQueryForm)
|
|
@@ -1601,7 +1366,7 @@ export default {
|
|
|
.catch(() => {
|
|
|
// 仅选择当前页
|
|
|
this.selectCurrentPage(selection);
|
|
|
- // 更新当前页的选择记录
|
|
|
+ // 更���当前页的选择记录
|
|
|
this.selectedPageIds.set(
|
|
|
currentPage,
|
|
|
new Set(selection.map((item) => item.id))
|
|
@@ -1645,13 +1410,13 @@ export default {
|
|
|
this.isAllSelected = false;
|
|
|
// 清除之前的选择
|
|
|
this.selectedTemplateIds.clear();
|
|
|
- // 添加当前页选中项
|
|
|
+ // ��加当前页选中项
|
|
|
selection.forEach((item) => {
|
|
|
this.selectedTemplateIds.add(item.id);
|
|
|
});
|
|
|
},
|
|
|
|
|
|
- // 获取��有模版数据
|
|
|
+ // 获取有模版数据
|
|
|
async getAllTemplates() {
|
|
|
const pageSize = 999; // 使用较大的页码一次性获取
|
|
|
const params = {
|
|
@@ -2010,6 +1775,20 @@ export default {
|
|
|
font-size: 12pt;
|
|
|
line-height: 1.5;
|
|
|
}
|
|
|
+ /* 添加图片控制样式 */
|
|
|
+ img {
|
|
|
+ max-width: 100%;
|
|
|
+ max-height: 100vh;
|
|
|
+ object-fit: contain;
|
|
|
+ page-break-inside: avoid;
|
|
|
+ }
|
|
|
+ /* 图片容器样式 */
|
|
|
+ .image-container {
|
|
|
+ width: 100%;
|
|
|
+ text-align: center;
|
|
|
+ margin: 10px 0;
|
|
|
+ page-break-inside: avoid;
|
|
|
+ }
|
|
|
table {
|
|
|
width: 100%;
|
|
|
border-collapse: collapse;
|
|
@@ -2027,7 +1806,7 @@ export default {
|
|
|
</style>
|
|
|
</head>
|
|
|
<body>
|
|
|
- ${contentContainer.innerHTML}
|
|
|
+ ${processImages(contentContainer.innerHTML)}
|
|
|
</body>
|
|
|
</html>`;
|
|
|
|
|
@@ -2096,6 +1875,20 @@ export default {
|
|
|
font-size: 12pt;
|
|
|
line-height: 1.5;
|
|
|
}
|
|
|
+ /* 添加图片控制样式 */
|
|
|
+ img {
|
|
|
+ max-width: 100%;
|
|
|
+ max-height: 100vh;
|
|
|
+ object-fit: contain;
|
|
|
+ page-break-inside: avoid;
|
|
|
+ }
|
|
|
+ /* 图片容器样式 */
|
|
|
+ .image-container {
|
|
|
+ width: 100%;
|
|
|
+ text-align: center;
|
|
|
+ margin: 10px 0;
|
|
|
+ page-break-inside: avoid;
|
|
|
+ }
|
|
|
table {
|
|
|
width: 100%;
|
|
|
border-collapse: collapse;
|
|
@@ -2113,7 +1906,7 @@ export default {
|
|
|
</style>
|
|
|
</head>
|
|
|
<body>
|
|
|
- ${contentContainer.innerHTML}
|
|
|
+ ${processImages(contentContainer.innerHTML)}
|
|
|
</body>
|
|
|
</html>`;
|
|
|
|
|
@@ -2144,10 +1937,50 @@ export default {
|
|
|
this.$message.success("导出成功");
|
|
|
return res.data; // 返回结果,包含 file_path
|
|
|
} catch (error) {
|
|
|
- console.error("导出PDF��败:", error);
|
|
|
+ console.error("导出PDF败:", error);
|
|
|
this.$alert("导出PDF时发生错误,请稍后重试。");
|
|
|
}
|
|
|
},
|
|
|
+ // 添加处理图片的辅助方法
|
|
|
+ processImages(content) {
|
|
|
+ const tempDiv = document.createElement('div');
|
|
|
+ tempDiv.innerHTML = content;
|
|
|
+
|
|
|
+ // 处理所有图片
|
|
|
+ tempDiv.querySelectorAll('img').forEach(img => {
|
|
|
+ // 保存原始宽高属性
|
|
|
+ const originalWidth = img.getAttribute('width');
|
|
|
+ const originalHeight = img.getAttribute('height');
|
|
|
+
|
|
|
+ // 创建图片容器
|
|
|
+ const container = document.createElement('div');
|
|
|
+ container.className = 'image-container';
|
|
|
+
|
|
|
+ // 设置图片样式
|
|
|
+ img.style.maxWidth = '100%';
|
|
|
+ img.style.height = 'auto';
|
|
|
+
|
|
|
+ // 如果有原始尺寸,使用原始尺寸(但确保不超过页面宽度)
|
|
|
+ if (originalWidth && originalHeight) {
|
|
|
+ const aspectRatio = originalWidth / originalHeight;
|
|
|
+ const maxWidth = 595; // A4纸宽度(像素,减去边距)
|
|
|
+
|
|
|
+ if (originalWidth > maxWidth) {
|
|
|
+ img.style.width = maxWidth + 'px';
|
|
|
+ img.style.height = (maxWidth / aspectRatio) + 'px';
|
|
|
+ } else {
|
|
|
+ img.style.width = originalWidth + 'px';
|
|
|
+ img.style.height = originalHeight + 'px';
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 将图片包装在容器中
|
|
|
+ img.parentNode.insertBefore(container, img);
|
|
|
+ container.appendChild(img);
|
|
|
+ });
|
|
|
+
|
|
|
+ return tempDiv.innerHTML;
|
|
|
+ },
|
|
|
},
|
|
|
};
|
|
|
</script>
|
|
@@ -2191,7 +2024,7 @@ export default {
|
|
|
font-weight: bold;
|
|
|
}
|
|
|
|
|
|
-// 添加PDF导相关样式
|
|
|
+// 添加PDF相关样式
|
|
|
.content {
|
|
|
background: white;
|
|
|
|