瀏覽代碼

提交页面

luogang 3 月之前
父節點
當前提交
d60af09230
共有 2 個文件被更改,包括 164 次插入14 次删除
  1. 158 0
      plus-ui-ts/src/utils/exportUtils.js
  2. 6 14
      plus-ui-ts/src/views/index.vue

+ 158 - 0
plus-ui-ts/src/utils/exportUtils.js

@@ -0,0 +1,158 @@
+// 导出工具文件 export-utils.js
+import { asBlob } from 'html-docx-js-typescript';
+import jsPDF from 'jspdf';
+import html2canvas from 'html2canvas';
+const exportUtils = {
+  // 导出Word
+  exportWord(htmlContent, fileName = 'document.docx') {
+    const content = `
+      <!DOCTYPE html>
+      <html>
+        <head>
+          <meta charset="utf-8">
+          <title>${fileName.replace('.docx', '')}</title>
+        </head>
+        <body>${htmlContent}</body>
+      </html>
+    `;
+
+    asBlob(content).then((data) => {
+      const url = URL.createObjectURL(data);
+      const a = document.createElement('a');
+      a.href = url;
+      a.download = fileName;
+      a.click();
+      URL.revokeObjectURL(url);
+    });
+  },
+
+  async exportPDF(element, fileName = 'document.pdf', options = {}) {
+    try {
+      // 创建隐藏的iframe
+      const iframe = document.createElement('iframe');
+      iframe.style.cssText = `
+        position: fixed;
+        top: -9999px;
+        left: -9999px;
+        width: 794px;  // A4宽度(210mm)减去边距,约794px(96dpi)
+        height: 1123px; // A4高度(297mm)约1123px
+        border: none;
+        visibility: hidden;
+      `;
+      document.body.appendChild(iframe);
+
+      // 准备iframe内容
+      const content = typeof element === 'string' ? element : element.outerHTML;
+      const style =
+        options.style ||
+        `
+        body {
+          margin: 0;
+          padding: 10mm;
+          font-size: 12pt;
+          font-family: "SimSun", "宋体", serif;
+        }
+        p {
+          text-indent: 2em;
+          margin: 0 0 12pt 0;
+          padding: 0;
+          line-height: 1.5;
+        }
+        table {
+          width: 100%;
+          border-collapse: collapse;
+        }
+        td, th {
+          border: 1px solid #ddd;
+          padding: 4px;
+        }
+      `;
+      // 写入iframe内容
+      iframe.contentDocument.open();
+      iframe.contentDocument.write(`
+        <!DOCTYPE html>
+        <html>
+          <head>
+            <meta charset="utf-8">
+            <style>${style}</style>
+            ${options.customCSS ? `<style>${options.customCSS}</style>` : ''}
+          </head>
+          <body>${content}</body>
+        </html>
+      `);
+      iframe.contentDocument.close();
+
+      // 等待iframe内容加载完成
+      await new Promise((resolve) => {
+        iframe.onload = resolve;
+        // 确保即使onload不触发也能继续
+        setTimeout(resolve, 500);
+      });
+
+      // 默认配置
+      const defaultOptions = {
+        scale: 2,
+        logging: false,
+        useCORS: true,
+        allowTaint: true,
+        backgroundColor: '#ffffff',
+        width: 794,
+        windowWidth: 794,
+        letterRendering: true,
+        // 使用iframe的body作为渲染目标
+        foreignObjectRendering: true,
+        // 确保iframe内容完全加载
+        async: true,
+        onclone: (clonedDoc) => {
+          // 可以在这里对克隆的文档进行最后调整
+          if (options.onClone) {
+            options.onClone(clonedDoc);
+          }
+        }
+      };
+
+      // 合并配置
+      const canvasOptions = { ...defaultOptions, ...options };
+
+      // 使用iframe的body作为渲染目标
+      const canvas = await html2canvas(iframe.contentDocument.body, canvasOptions);
+
+      // 创建PDF
+      const imgData = canvas.toDataURL('image/png');
+      const pdf = new jsPDF('p', 'mm', 'a4');
+      const imgWidth = 190; // A4宽度减去边距(210-20)
+      const imgHeight = (canvas.height * imgWidth) / canvas.width;
+
+      pdf.addImage(imgData, 'PNG', 10, 10, imgWidth, imgHeight);
+
+      // 处理多页内容(如果需要)
+      let heightLeft = imgHeight - (297 - 20); // 剩余高度
+      let position = 10; // 当前位置
+      let pageCount = 1;
+
+      while (heightLeft >= 0 && pageCount < 10) {
+        // 限制最多10页
+        pdf.addPage();
+        position = heightLeft - imgHeight;
+        pdf.addImage(imgData, 'PNG', 10, position, imgWidth, imgHeight);
+        heightLeft -= 297 - 20;
+        pageCount++;
+      }
+
+      // 保存文件
+      pdf.save(fileName);
+
+      // 移除iframe
+      document.body.removeChild(iframe);
+
+      return true;
+    } catch (error) {
+      console.error('导出PDF失败:', error);
+      // 确保出错时也移除iframe
+      const iframes = document.querySelectorAll('iframe[style*="-9999px"]');
+      iframes.forEach((iframe) => document.body.removeChild(iframe));
+      throw error;
+    }
+  }
+};
+export default exportUtils;

+ 6 - 14
plus-ui-ts/src/views/index.vue

@@ -237,7 +237,6 @@
             <el-select style="width: 300px; margin-top: 10px" v-model="fileType" clearable placeholder="请选择">
               <el-option label="pdf" :value="1"></el-option>
               <el-option label="word" :value="2"></el-option>
-              <el-option label="图片" :value="3"></el-option>
             </el-select>
           </div>
           <div>
@@ -255,7 +254,7 @@ import monitorIcon from '@/assets/images/monitor.svg';
 import DPlayer from 'dplayer';
 import '@wangeditor/editor/dist/css/style.css'; // 引入 css
 import { Editor, Toolbar } from '@wangeditor/editor-for-vue';
-import { exportAsPdf, exportAsWord, exportAsImage } from 'html2image-pdf-word';
+import exportUtils from '@/utils/exportUtils';
 import { listEvent, generateReport, updateEvent } from '@/api/system/event';
 import { dateFormat } from '@/utils/index';
 import { ElLoading } from 'element-plus';
@@ -287,19 +286,12 @@ const handleCreated = (editor) => {
 const fileType = ref(1);
 const showReport = ref(false);
 const htmlToPdfFn = async () => {
-  const dom: any = document.querySelector('.w-e-text-container');
-  const filename = '报告';
+  const dom = document.querySelector('.w-e-text-container');
   const type = fileType.value;
-  switch (type) {
-    case 1:
-      await exportAsPdf(dom, filename);
-      break;
-    case 2:
-      await exportAsWord(dom, filename);
-      break;
-    case 3:
-      await exportAsImage(dom, filename);
-      break;
+  if (type == 1) {
+    exportUtils.exportPDF(dom, '报告.pdf');
+  } else if (type == 2) {
+    exportUtils.exportWord(valueHtml.value, '报告.docx');
   }
 };