使用webworker实现多线程处理大量数据上传

使用webworker.js文件定义

// 导入 xlsx 库
importScripts('https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.16.9/xlsx.full.min.js');

// 监听主线程发送的文件消息
onmessage = function(event) {
  const file = event.data;

  // 调用解析 Excel 文件的函数
  parseExcelFile(file);
};

// 解析 Excel 文件的函数
function parseExcelFile(file) {
  const reader = new FileReader();

  reader.onload = function(e) {
    const data = new Uint8Array(e.target.result);
    const workbook = XLSX.read(data, { type: 'array' });

    // 存储解析后的数据
    let parsedData = [];

    // 遍历工作表
    workbook.SheetNames.forEach(function(sheetName) {
      const worksheet = workbook.Sheets[sheetName];
      const jsonData = XLSX.utils.sheet_to_json(worksheet, { header: 1 });
      parsedData.push({ sheetName: sheetName, jsonData: jsonData });
    });

    // 向主线程发送解析后的数据
    postMessage(parsedData);
  };

  reader.readAsArrayBuffer(file);
}

在我们.vue文件中

<template>
  <div>
    <input
      type="file"
      @change="handleFileUpload"
      id="fileInput"
      accept=".xlsx, .xls, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel"
    />
    <ul>
      <li v-for="(item, index) in importedData" :key="index">
        <strong>{{ item.sheetName }}</strong>:
        <ul>
          <li v-for="(row, rowIndex) in item.jsonData" :key="rowIndex">
            {{ row }}
          </li>
        </ul>
      </li>
    </ul>
    <hr />

    <button @click="downloadExcel">生成并下载</button>
  </div>
</template>

<script setup lang="ts">
import axios from "axios";
import { ref } from "vue";

const importedData = ref([]);

const handleFileUpload = (event: Event) => {
  const target = event.target as HTMLInputElement;
  const file = target.files?.[0];

  if (!file) return;

  // 创建 Web Worker
  const worker = new Worker(new URL("./excelWorker.js", import.meta.url));

  // 向 Web Worker 发送消息(文件对象)
  worker.postMessage(file);

  // 监听 Web Worker 返回的消息
  worker.onmessage = (event) => {
    importedData.value = event.data;
    console.log("Imported data:", importedData.value);

    // 结束 Worker
    worker.terminate();
  };

  // 监听 Web Worker 报告的错误
  worker.onerror = (error) => {
    console.error("Worker error:", error);
  };
};

//请求的接口
const downloadExcel = async () => {
  try {
    const response = await axios.get("http://localhost:3000/generate-excel", {
      responseType: "blob", // 告诉 Axios 返回的是二进制数据
    });

    // 创建 Blob 对象
    const blob = new Blob([response.data], {
      type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
    });

    // 创建下载链接
    const url = URL.createObjectURL(blob);

    // 创建一个<a>元素并设置属性
    const link = document.createElement("a");
    link.href = url;
    link.download = "patients.xlsx"; // 下载文件名

    // 点击<a>元素进行下载
    link.click();

    // 清理 URL 对象
    URL.revokeObjectURL(url);
  } catch (error) {
    console.error("下载出错:", error);
  }
};
</script>

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用Web Worker来计算大量数据贴地的过程可以分为以下几步: 1. 在主线程中创建一个Web Worker对象,指定要执行的计算任务的代码文件路径。 ```javascript const worker = new Worker('worker.js'); ``` 2. 在Worker代码文件中,使用postMessage()方法将计算任务分发到Worker线程中执行。 ```javascript // worker.js self.addEventListener('message', (e) => { const data = e.data; // 执行计算任务 const result = calculate(data); // 将计算结果发送回主线程 self.postMessage(result); }); ``` 3. 在主线程中监听Worker线程的message事件,获取计算结果。 ```javascript worker.addEventListener('message', (e) => { const result = e.data; // 处理计算结果 }); ``` 4. 将需要计算的大量数据分割成小块,逐个发送给Worker线程进行计算,并在计算完成后合并结果。 ```javascript const chunkSize = 1000; // 每次处理数据块大小 const totalChunks = Math.ceil(data.length / chunkSize); // 数据块数量 let completedChunks = 0; // 已完成的数据块数量 let results = []; // 存储计算结果 for (let i = 0; i < totalChunks; i++) { const start = i * chunkSize; const end = Math.min(start + chunkSize, data.length); const chunk = data.slice(start, end); // 发送数据块到Worker线程 worker.postMessage(chunk); // 监听计算结果 worker.addEventListener('message', (e) => { const result = e.data; results.push(result); completedChunks++; if (completedChunks === totalChunks) { // 所有数据块都已计算完成,处理最终结果 const finalResult = mergeResults(results); // TODO: 处理最终结果 } }); } ``` 5. 在Worker线程中,使用Cesium的SampledProperty对象对贴地数据进行插值计算,并将计算结果返回给主线程。 ```javascript // worker.js import { SampledProperty } from 'cesium'; function calculate(data) { const property = new SampledProperty(Number); // 创建一个SampledProperty对象 // 向SampledProperty对象添加样本点,x轴为时间,y轴为高度 for (let i = 0; i < data.length; i++) { const time = data[i].time; const height = data[i].height; property.addSample(time, height); } // 对SampledProperty对象进行插值计算,获取贴地高度值 const result = []; for (let i = 0; i < data.length; i++) { const time = data[i].time; const position = data[i].position; const height = property.getValue(time); result.push({ position, height }); } return result; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值