<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      《vue實現(xiàn)動態(tài)生成并導出world功能》

      1. 安裝需要的插件并引入

      import PizZip from 'pizzip'
      import Docxtemplater from 'docxtemplater'
      import JSZipUtils from 'jszip-utils'
      import { saveAs } from 'file-saver'
      import ImageModule from 'docxtemplater-image-module-free'
      import { Buffer } from 'buffer'

      2. 工具utils中新建 exportFile.js 文件,用于將圖片轉(zhuǎn)換為base64格式

      // getBase64Sync
      export function getBase64Sync(imgUrl) {
        return new Promise((resolve, reject) => {
          const image = new Image();
          image.crossOrigin = 'anonymous';
          image.onload = () => {
            const canvas = document.createElement('canvas');
            // 固定畫布尺寸為90x90
            canvas.width = 90;
            canvas.height = 90;
            const ctx = canvas.getContext('2d');
            // 計算縮放比例后居中繪制
            const scale = Math.min(90 / image.width, 90 / image.height);
            const scaledWidth = image.width * scale;
            const scaledHeight = image.height * scale;
            const dx = (90 - scaledWidth) / 2;
            const dy = (90 - scaledHeight) / 2;
            ctx.drawImage(image, dx, dy, scaledWidth, scaledHeight);
      
            let ext = imgUrl.split('.').pop().toLowerCase();
            if (ext === 'jpg') ext = 'jpeg';
            const mime = `image/${ext}`;
            try {
              const dataurl = canvas.toDataURL(mime, 0.8);
              resolve(dataurl);
            } catch (e) {
              reject(e);
            }
          };
          image.onerror = () => reject(new Error('圖片加載失敗'));
          image.src = imgUrl + (imgUrl.includes('?') ? '&' : '?') + 't=' + Date.now();
        });
      }
      
      // base64DataURLToArrayBuffer
      export function base64DataURLToArrayBuffer(dataURL) {
        const base64 = dataURL.split(',')[1];
        const binaryString = window.atob(base64);
        const len = binaryString.length;
        const bytes = new Uint8Array(len);
        for (let i = 0; i < len; i++) {
          bytes[i] = binaryString.charCodeAt(i);
        }
        return bytes.buffer;
      }

      3.引入 exportFile中的函數(shù)

      import { getBase64Sync,base64DataURLToArrayBuffer } from '@/utils/exportFile.js'

      4.設置.docx模板文件,位置放在public文件下

      數(shù)組使用{#data}{/data}包裹起來

      展示的字段使用{item}

      圖片賦值用到{%img}

      模板例如:

       

      5.導出按鈕具體功能實現(xiàn)

      /** 方案1,不考慮圖片直接導出 world */
      function submitForm() {
        // const htmlContent = document.getElementById('htmlcontent');
        // const blob = new Blob([htmlContent.innerHTML], { type: 'application/msword' });
        // const url = window.URL.createObjectURL(blob);
        // const a = document.createElement('a');
        // a.href = url;
        // a.download = '包裝碼.docx';
        // a.click();
        // window.URL.revokeObjectURL(url);
      }
      /** 方案2,考慮圖片,導出world */
      async function exportWord() {
        try {
          const content = await new Promise((resolve, reject) => {
      //world模板'/boxCode.docx' JSZipUtils.getBinaryContent('/boxCode.docx?random=' + Math.random(), (error, data) => { error ? reject(error) : resolve(data); }); }); const zip = new PizZip(content); let doc = new Docxtemplater(); // 注冊圖片模塊 const imageOptions = { getImage: (tag) => { const base64Data = tag.split(',')[1]; return Buffer.from(base64Data, 'base64'); }, // 設置Word中圖片顯示尺寸為90x90 getSize: () => [90, 90] }; doc.attachModule(new ImageModule(imageOptions)); doc.loadZip(zip); const processedData = await Promise.all( currentData.value.map(async (item) => { const base64 = await getBase64Sync(item.boxCodeUrl); const matches = base64.match(/^data:image\/(\w+);base64,/); const validBase64 = matches ? base64 : `data:image/png;base64,${base64}`; //圖片轉(zhuǎn)碼 return { itemCode:item.itemCode?item.itemCode:'', batchNumber:item.batchNumber?item.batchNumber:'', itemName:item.itemName?item.itemName:'', itemModel:item.itemModel?item.itemModel:'', itemNumber:item.itemNumber?item.itemNumber:'', projectName:item.projectName?item.projectName:'', specification:item.specification?item.specification:'', vendorName:item.vendorName?item.vendorName:'', boxCodeUrl: validBase64 || '' }; }) ) doc.setData({ currentData: processedData });//數(shù)據(jù)賦值 try { doc.render(); } catch (error) { console.error('模板渲染錯誤:', error.properties?.errors); throw error; } const out = doc.getZip().generate({ type: 'blob', mimeType: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' }); saveAs(out, currentItemName.value + '包裝碼.docx'); } catch (error) { console.error('導出失敗:', error); throw error; }finally{ visible.value = false } }

      6.導出的world頁面中若需要分頁,在需要分頁的光標位置設置分頁符

       注:因為我用到了標簽打印,生成的world打印時縱向橫向樣式展示沒辦法解決,所以將生成的world通過接口轉(zhuǎn)為pdf輸出進行打印
      // 生成Word Blob 發(fā)送到后端轉(zhuǎn)換服務
          const selectedFile = doc.getZip().generate({ 
            type: 'blob',
            mimeType: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
          });
          const formData = new FormData();
          formData.append('file', selectedFile);
          fetch(VITE_APP_BASE_API + VITE_AGENT_API+`/md/purchaseorder/convertWordToPDF`, {
              method: 'POST',
              headers: {
                  'Authorization': `Bearer ${getToken()}`
              },
              body: formData
          })
          .then(response => {
              if (!response.ok) {
                  throw new Error(`服務器返回錯誤: ${response.status}`);
              }
              return response.blob();
          })
          .then(blob => {
            const url = window.URL.createObjectURL(blob);
            const link = document.createElement('a');
            link.href = url;
            link.setAttribute('download', `${currentItemName.value}` + '包裝碼.pdf' );
            document.body.appendChild(link);
            link.click();
            document.body.removeChild(link);
          })
          .catch(error => {
            console.error('導出失敗:', error);
            loadingSubmit.value = false
            throw error;
          });

       

       

       

      posted @ 2025-05-08 09:29  愛聽書的程序猿  閱讀(94)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 在线国产毛片| 免费观看羞羞视频网站 | 国产视频不卡一区二区三区| A级毛片无码久久精品免费| 久久精品国产一区二区三区| 国产视频一区二区三区四区视频| 欧美成年黄网站色视频| 国偷自产av一区二区三区| 国产麻豆精品一区一区三区| 四虎永久精品免费视频| 久久三级中文欧大战字幕| 亚洲成人av综合一区| 老司机精品成人无码AV| 日韩中文字幕亚洲精品一| 免费av网站| 久久日韩在线观看视频| 成年入口无限观看免费完整大片| 白白发布视频一区二区视频| 少妇粗大进出白浆嘿嘿视频| 精品国产乱弄九九99久久| 国产喷水1区2区3区咪咪爱AV| 五月婷婷久久中文字幕| 成人片黄网站色大片免费毛片 | 国产免费爽爽视频| 你懂的亚洲一区二区三区| 日本一道一区二区视频| 国产成人午夜福利在线播放| 大屁股肥熟女流白浆| 国产精品一区二区三区av| 美女裸体黄网站18禁止免费下载 | 国产啪视频免费观看视频| 国产成人久久精品二区三| 最新国产精品中文字幕| 四虎国产精品永久在线| 亚洲色成人网站www永久下载| 亚洲最大有声小说AV网| 九九久久自然熟的香蕉图片| 中国少妇无码专区| 无套内谢少妇一二三四| 亚洲av日韩av中文高清性色| 91在线视频视频在线|