webworker

86 阅读2分钟

安装

"worker-loader": "^1.1.1"

worker-loader在2.0.0之后不再支持webpack3 因此如果webpack3需要安装1版本 webpack5/vite则可以使用new Worker(new URL('worker.js', import.meta.url))的方式

配置

{
        test: /.Worker.js$/,  // 匹配所有的xxx.worker.js
        loader: 'worker-loader'
      },

主应用 vue

import Worker from './test.Worker.js'
 const worker = new Worker() // 直接创建实例

          // 向worker线程发送消息
          worker.postMessage({
            interBaseInfo: this.intersection_base_info,
            acsInfo: this.acs_info,
            rlscInfo: this.rlsc_infos,
            interData: this.interData,
            acsLight: this.acsLight,
            schemeDetailList: this.schemeDetailList,
            interDispatch: this.interDispatch, 
            vlcPlan: this.vlcPlan,
            vlcDispatchPlan: this.vlcDispatchPlan
          })

test.Worker.js 可是webworker中不能操作docuemnt

// 监听消息
import Docxtemplater from "docxtemplater";
import PizZip from "pizzip";
import JSZipUtils from "jszip-utils";
import ImageModule from "docxtemplater-image-module-free";
import { saveAs } from "file-saver";
import html2canvas from 'html2canvas'
import mammoth from "mammoth";
import { phaseMap, getPhaseDec, interOption, enterDirectionMap } from '@/common/js/common_acs.js'
const roadShapesMap = new Map();
roadShapesMap.set(2, "一字路口");
roadShapesMap.set(3, "T型路口");
roadShapesMap.set(4, "十字路口");
roadShapesMap.set(5, "五叉路口");
const roadHaveSonsMap = new Map();
roadHaveSonsMap.set(0, "普通路口");
roadHaveSonsMap.set(1, "父子路口");
roadHaveSonsMap.set(2, "匝道路口");
const categoryIcon = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAARCAYAAADUryzEAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAICSURBVHgBrVM9ctNQEP5WliGZgRlxA5kLIChpSKgZ4twgqSixaajAygwzlHY4AKaki1MxQ+M00NpwAZmSys/GtiLZ1rJPT1IUJ+myI82u9u379tsfAbct/0LeWcTcPo85iJbM+hV7EMbcDUN2N+MpN4IxO9tAy7LQ4ItDZhPDlDlWaxxHwFHtAakCIAjYie+gL1/edayIBIgvkok9vBtjt1YjZWvH3yVatIK3GWhyp9r42ICJ9WiVoCW6Sd8G7ArtYKOuUdXCIe5huCtZ+r+5HjPacuSyAdFBnKzxnL7+4K44Dkp0g+oWnuw/NjXmcjKQMkMM5KKbsWJO8MmaLOCpBXg8B0RjOsebzctatG8a4XA8S+NYzUAqxJ4tHx4bxLS+ty+phxtkpjCMraI7WlxLo01CQdQM5iD/hJ2bAJr7pFTGNNNsC/U/AufmQazSUZ5dB/DqM+/pUrNeafllSc2nY5MdqY7QrbevstA+NUVH2BYMJucY0ouPvLMG+mwmDmL9YCQjan5/R726z86sAs+uQE8rnYAJBG8BD1MiT99zR0byOm9Psb+XSWStNiK9PP75gRrpJi6m8KMKnkmImUhWo9gsmjhnlqGSJat8Hz7KiG6DnWWE1jpBo5ST0zUu5a4Aneo2jkad0s9UFueA3WUCP5F9LxgRRjbh1LbQU1/orBz/H0Z7C4MpXAiIAAAAAElFTkSuQmCC'

onmessage = function(e) {
  console.log('监听到的消息为11:' + e.data);
  const {interBaseInfo, acsInfo, rlscInfo, interData, acsLight, schemeDetailList, interDispatch, vlcPlan, vlcDispatchPlan} = e.data
  console.log('rlscInfo,,,,', rlscInfo)
  exportDocx(interBaseInfo, acsInfo, rlscInfo, interData, acsLight, schemeDetailList, interDispatch, vlcPlan, vlcDispatchPlan)
}

function  getStaticPath(appendPath) {
      const origin = location.origin;
      const pathNameArr = location.pathname.split("\/");
      const linkPath = pathNameArr.slice(0, pathNameArr.length - 2).join("\/");
      const configFile = `${origin}${linkPath}${appendPath}`;
      return configFile;
    }
async function exportDocx(interBaseInfo, acsInfo, rlscInfo, interData, acsLight, schemeDetailList, interDispatch, vlcPlan, vlcDispatchPlan) {
    // 可变车道设备
    rlscInfo.forEach((item, index) => {
    item.index = index + 1
    item.name = item.name || ''
    })
    // 信号灯
    acsLight.forEach(item => {
    for (let i = 0; i < 7; i++) {
        item['move'+(i+ 1)] = item.movements[i] || ''
    }
    })
    // 方案
    const no_flow = getStaticPath("/common/no_img.png")
    const promise = []
    schemeDetailList.forEach((item, i) => {
    item.schemeImage = no_flow
    let element = document.querySelector(`#scheme-${i}`)
    promise.push(html2canvas(element))
    })
    const result = await Promise.all(promise)
    result.forEach((canvas, index) => {
    if (canvas) {
        // console.log('html2canvas canvas,,toDataURL,,', canvas.toDataURL())
    }
    schemeDetailList[index].schemeImage = canvas?.toDataURL() || no_flow
    })
    // 方案调度
    for (let k = 0; k < interDispatch.length; k++) {
    let acsDispatchPromise = []
    interDispatch[k].scheme_dispatchs.forEach((scheme, j) => {
        scheme.start_time = scheme.time_frame && scheme.time_frame.split('-')[0]
        scheme.scheme_name = scheme.scheme_name || ''
        scheme.schemeImage = no_flow
        let element = document.querySelector(`#dispatch-${k}-${j}`)
        console.log('element,,,', element)
        acsDispatchPromise.push(html2canvas(element))
    })
    console.log('acsDispatchPromise,,,', acsDispatchPromise)
    let result = await Promise.all(acsDispatchPromise)
    console.log('result,,,', result)
    result.forEach((canvas, index) => {
        if (canvas) {
        console.log('html2canvas canvas,,toDataURL,,', canvas.toDataURL())
        }
        interDispatch[k].scheme_dispatchs[index].dispatchSchemeImage = canvas?.toDataURL() || no_flow
    })
    }

    // 可变车道方案
    let vlcSchemePromise = []
    for (let v = 0; v < vlcPlan.length; v++) {
    let element = document.querySelector(`#vlcScheme-${v}`)
    vlcSchemePromise.push(html2canvas(element))
    }
    const vlcSchemeResult = await Promise.all(vlcSchemePromise)
    vlcSchemeResult.forEach((canvas, index) => {
    vlcPlan[index].vlcSchemeImage = canvas?.toDataURL() || no_flow
    })
    // 可变车道方案调度
    for(let w = 0; w < vlcDispatchPlan.length; w++) {
    let vlcDispatchSchemePromise = []
    vlcDispatchPlan[w].vlc_period_schemes.forEach((scheme, j) => {
        scheme.period_time = scheme.start_time + '_' + scheme.end_time
        let element = document.querySelector(`#vlcDispatchScheme-${w}-${j}`)
        vlcDispatchSchemePromise.push(html2canvas(element))
    })
    let result = await Promise.all(vlcDispatchSchemePromise)
    console.log('result,,,', result)
    result.forEach((canvas, index) => {
        if (canvas) {
        console.log('html2canvas canvas,,toDataURL,,', canvas.toDataURL())
        }
        vlcDispatchPlan[w].vlc_period_schemes[index].vlcDispatchSchemeImage = canvas?.toDataURL() || no_flow
    })
    }
    console.log('interDispatch,,,,', interDispatch)
    console.log('vlcPlan,,,,', vlcPlan)
    console.log('vlcDispatchPlan,,,,', vlcDispatchPlan)
    // 导出时间
    const nowDate = new Date();
    const exportYear = nowDate.getFullYear();
    let exportMonth = nowDate.getMonth() + 1;
    exportMonth = exportMonth < 10 ? "0" + exportMonth : exportMonth;
    let exportDay = nowDate.getDate();
    exportDay = exportDay < 10 ? "0" + exportDay : exportDay;
    let exportHour = nowDate.getHours();
    exportHour = exportHour < 10 ? "0" + exportHour : exportHour;
    let exportMin = nowDate.getMinutes();
    exportMin = exportMin < 10 ? "0" + exportMin : exportMin;
    // 导出文件拼接信号机名称
    this.interName = interBaseInfo.name;
    // 交叉类型
    let roadShape = "---";
    const interOrientionEnIdMap = new Map(); // 方向和进口id
    const interEnterNameIdMap = new Map(); // 进口id和名称
    if (interData) {
    roadShape = roadHaveSonsMap.get(interData.is_have_son);
    if (interData.is_have_son === 2) {

    } else if (interData.is_have_son === 1) {
        roadShape += ` 父${roadShapesMap.get(interData.shape)} 子${roadShapesMap.get(interData.son_shape)}`;
    } else if (interData.is_have_son === 0) {
        roadShape += ` ${roadShapesMap.get(interData.shape)}`;
    }
    interData.entrances.forEach(entrance => {
        interOrientionEnIdMap.set(entrance.orientation, entrance.en_id);
        interEnterNameIdMap.set(entrance.en_id, entrance.name);
    });
    interData.son_entrances.forEach(entrance => {
        interOrientionEnIdMap.set(entrance.orientation, entrance.en_id);
        interEnterNameIdMap.set(entrance.en_id, entrance.name);
    });
    }
    
    const docxUrl = getStaticPath("/common/inter_plan_infos_templates.docx");
    const no_img_url = getStaticPath("/common/no_img.png");
    console.log('JSZipUtils.getBinaryConten')
    JSZipUtils.getBinaryContent(docxUrl, async (err, content) => {
    if (err) {
        throw err;
    }
    let interImg = no_img_url
    const divElement = document.querySelector('.inter-model-wrap')
    if (divElement) {
        const result = await html2canvas(divElement)
        interImg = result?.toDataURL() || no_flow
    }
    
    
    // const curPlanExportDate = `${exportYear}.${exportMonth}.${exportDay} ${exportHour}:${exportMin}`;
    const opts = {
        centered: false,
        getImage(tagValue, tagName) {
        return new Promise((resolve, reject) => {
            JSZipUtils.getBinaryContent(tagValue, (error, content) => {
            if (error) {
                return reject(error);
            }
            return resolve(content);
            });
        });
        },
        getSize(img, tagValue, tagName) {
        if (tagName === "interImg") {
            return [600, 375];
        } else if (tagName.includes("flowUrl")) {
            return [75, 75];
        } else if (tagName === "categoryIcon") {
            return [15, 18];
        } else if (tagName.includes("schemeImage")) {
            return [600, 90]
        } else if (tagName === "dispatchSchemeImage") {
            return [300, 55]
        } else if (tagName === 'vlcSchemeImage' || tagName === 'vlcDispatchSchemeImage') {
            return [600, 180]
        }
        return [110, 110]
        }
    };
    
    const imageModule = new ImageModule(opts);
    const zip = new PizZip(content);
    const doc = new Docxtemplater().loadZip(zip)
        .attachModule(imageModule).compile();
    console.log('doc.resolveData')
    doc.resolveData({
        categoryIcon,
        name: interBaseInfo.name,
        inter_id: interBaseInfo.intersection_id,
        exportYear: exportYear,
        exportMonth: exportMonth,
        exportDay: exportDay,
        maintenance_unit: interBaseInfo.maintenance_unit,
        construction_unit: interBaseInfo.construction_unit,
        unit_name: interBaseInfo.unit_name,
        region: interBaseInfo.region || '',
        acsName: acsInfo.name,
        device_factory: acsInfo.device_factory,
        dev_type: acsInfo.dev_type,
        ip: acsInfo.ip,
        port: acsInfo.port,
        roadShape: roadShape,
        interImg: interImg || no_img_url,
        rlsc_infos: rlscInfo,
        acsLight: acsLight,
        schemeDetailList,
        interDispatch,
        vlcPlan, 
        vlcDispatchPlan
        // max_phase_num: tzcsData.max_phase_num,
        // curPlanExportDate: curPlanExportDate,
        // curPlanInfos: curPlanInfos,
        // curPlanRunInfos: curPlanRunInfos,
        // lightTypeArrs: lightTypeArrs,
        // lastPlanInfos: lastPlanInfos,
        // lastPlanRunInfos: lastPlanRunInfos,
        // last_max_phase_num: lastTzcsData.max_phase_num,
        // historyDownCharArr: historyDownCharArr,
        // lastPlanRunTime,
        // lastDownloadTime
        // "complexXml": "<w:p><w:pPr><w:rPr><w:color w:val=\"FF0000\"/></w:rPr></w:pPr><w:r><w:rPr><w:color w:val=\"FF0000\"/></w:rPr><w:t>My custom</w:t></w:r><w:r><w:rPr><w:color w:val=\"00FF00\"/></w:rPr><w:t>XML</w:t></w:r></w:p>"
    }).then(() => {
        // doc.setData({
        //   name: this.acsInfo.name,
        //   acs_id: this.acsInfo.acs_id,
        //   exportYear: this.acsInfo.exportYear,
        //   exportMonth: this.acsInfo.exportMonth,
        //   exportDay: this.acsInfo.exportDay,
        //   unit1: this.acsInfo.unit1,
        //   unit2: this.acsInfo.unit2,
        //   acs_version: this.acsInfo.acs_version,
        //   versionDate: this.acsInfo.versionDate,
        //   ip: this.acsInfo.ip,
        //   interImg: this.acsInfo.interImg,
        //   lightTypeArrs: this.lightTypeArrs,
        // });
        try {
        doc.render();
        } catch (err) {
        throw err;
        }
        const out = doc.getZip().generate({
        type: "blob",
        mimeType: "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
        });
        this.outContent = out;

        // const reader = new FileReader();
        // reader.readAsArrayBuffer(out);
        // const that = this;
        // reader.onload = function(e) {
        //   const buffer = e.target.result; // 此时是arraybuffer类型
        //   mammoth.convertToHtml({ arrayBuffer: buffer }).then((result) => {
        //     const ele = document.createElement("div");
        //     ele.innerHTML = result.value;
        //     that.changeEleNode(ele);
        //     that.vHtml = ele.innerHTML;
        //   }).done();
        // };
        // saveAs(out, this.acsInfo.name + "交叉路口模板");
    });
    });
}
function exportToDoc() {
    saveAs(this.outContent, this.interName + "路口档案" + ".doc");
}

juejin.cn/post/699633…