mirror of
https://gitee.com/kekingcn/file-online-preview.git
synced 2026-09-13 00:14:56 +00:00
Optimize LuckyExcel xlsx preview conversion with Web Worker (#766)
* Optimize LuckyExcel conversion with worker * Fallback LuckyExcel worker errors to main thread
This commit is contained in:
54
server/src/main/resources/static/xlsx/luckyexcel-worker.js
Normal file
54
server/src/main/resources/static/xlsx/luckyexcel-worker.js
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
// LuckyExcel's bundled getBinaryContent reads window.XMLHttpRequest.
|
||||||
|
// Web Worker exposes XMLHttpRequest on self, so provide a minimal window alias
|
||||||
|
// before loading the UMD bundle.
|
||||||
|
self.window = self;
|
||||||
|
|
||||||
|
importScripts('./luckyexcel.umd.js');
|
||||||
|
|
||||||
|
self.console.log = function () {};
|
||||||
|
|
||||||
|
self.onmessage = function (event) {
|
||||||
|
var data = event.data || {};
|
||||||
|
var url = data.url;
|
||||||
|
var name = data.name;
|
||||||
|
|
||||||
|
if (!url) {
|
||||||
|
self.postMessage({
|
||||||
|
type: 'error',
|
||||||
|
message: '文件URL为空'
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
LuckyExcel.transformExcelToLuckyByUrl(
|
||||||
|
url,
|
||||||
|
name,
|
||||||
|
function (exportJson, luckysheetfile) {
|
||||||
|
if (!exportJson || !exportJson.sheets || exportJson.sheets.length === 0) {
|
||||||
|
self.postMessage({
|
||||||
|
type: 'error',
|
||||||
|
message: '读取excel文件内容失败!'
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.postMessage({
|
||||||
|
type: 'success',
|
||||||
|
exportJson: exportJson
|
||||||
|
});
|
||||||
|
},
|
||||||
|
function (error) {
|
||||||
|
self.postMessage({
|
||||||
|
type: 'error',
|
||||||
|
message: error && error.message ? error.message : String(error)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
self.postMessage({
|
||||||
|
type: 'error',
|
||||||
|
message: error && error.message ? error.message : String(error)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -3938,7 +3938,7 @@ var LuckySheet = /** @class */function (_super) {
|
|||||||
_this.sheetList = allFileOption.sheetList;
|
_this.sheetList = allFileOption.sheetList;
|
||||||
_this.imageList = allFileOption.imageList;
|
_this.imageList = allFileOption.imageList;
|
||||||
_this.hide = allFileOption.hide;
|
_this.hide = allFileOption.hide;
|
||||||
console.log(allFileOption, 'allFileOption');
|
// console.log(allFileOption, 'allFileOption');
|
||||||
_this.dataVerificationSelectCount = allFileOption.dataVerificationSelectCount;
|
_this.dataVerificationSelectCount = allFileOption.dataVerificationSelectCount;
|
||||||
//Output
|
//Output
|
||||||
_this.name = sheetName;
|
_this.name = sheetName;
|
||||||
|
|||||||
@@ -225,8 +225,11 @@
|
|||||||
// 使用异步方式加载
|
// 使用异步方式加载
|
||||||
await new Promise(resolve => setTimeout(resolve, 100)); // 给UI更新一点时间
|
await new Promise(resolve => setTimeout(resolve, 100)); // 给UI更新一点时间
|
||||||
|
|
||||||
// 或者使用现有的同步方法,但放在setTimeout中避免阻塞
|
const exportJson = await transformWithWorker(value, name);
|
||||||
await transformWithTimeout(value, name);
|
|
||||||
|
updateProgress(80);
|
||||||
|
|
||||||
|
await createLuckysheet(exportJson);
|
||||||
|
|
||||||
updateProgress(100);
|
updateProgress(100);
|
||||||
|
|
||||||
@@ -243,23 +246,81 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 使用setTimeout将同步任务拆分
|
function transformWithWorker(value, name) {
|
||||||
function transformWithTimeout(value, name) {
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
updateProgress(50);
|
updateProgress(50);
|
||||||
|
|
||||||
// 将转换过程放在setTimeout中,避免阻塞主线程
|
if (!window.Worker) {
|
||||||
setTimeout(() => {
|
transformOnMainThread(value, name, resolve, reject);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let worker;
|
||||||
try {
|
try {
|
||||||
LuckyExcel.transformExcelToLuckyByUrl(value, name, function(exportJson, luckysheetfile){
|
worker = new Worker('xlsx/luckyexcel-worker.js');
|
||||||
if(exportJson.sheets==null || exportJson.sheets.length==0){
|
} catch (error) {
|
||||||
|
transformOnMainThread(value, name, resolve, reject);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let settled = false;
|
||||||
|
const fallbackToMainThread = function(error) {
|
||||||
|
if (settled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
settled = true;
|
||||||
|
worker.terminate();
|
||||||
|
if (error) {
|
||||||
|
console.warn('Excel Worker转换失败,回退主线程转换:', error);
|
||||||
|
}
|
||||||
|
transformOnMainThread(value, name, resolve, reject);
|
||||||
|
};
|
||||||
|
|
||||||
|
worker.onmessage = function(event) {
|
||||||
|
const data = event.data || {};
|
||||||
|
|
||||||
|
if (data.type === 'success') {
|
||||||
|
settled = true;
|
||||||
|
worker.terminate();
|
||||||
|
resolve(data.exportJson);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.type === 'error') {
|
||||||
|
fallbackToMainThread(data.message || 'Excel转换失败');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
worker.onerror = function(error) {
|
||||||
|
fallbackToMainThread(error && error.message ? error.message : error);
|
||||||
|
};
|
||||||
|
|
||||||
|
worker.postMessage({
|
||||||
|
url: value,
|
||||||
|
name: name
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function transformOnMainThread(value, name, resolve, reject) {
|
||||||
|
try {
|
||||||
|
LuckyExcel.transformExcelToLuckyByUrl(value, name, function(exportJson, luckysheetfile) {
|
||||||
|
if (!exportJson || !exportJson.sheets || exportJson.sheets.length === 0) {
|
||||||
reject(new Error("读取excel文件内容失败!"));
|
reject(new Error("读取excel文件内容失败!"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
updateProgress(80);
|
resolve(exportJson);
|
||||||
|
}, function(error) {
|
||||||
|
reject(error);
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
reject(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 使用requestAnimationFrame来更新UI,避免阻塞
|
function createLuckysheet(exportJson) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
requestAnimationFrame(() => {
|
requestAnimationFrame(() => {
|
||||||
try {
|
try {
|
||||||
window.luckysheet.destroy();
|
window.luckysheet.destroy();
|
||||||
@@ -305,12 +366,6 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
} catch (error) {
|
|
||||||
reject(error);
|
|
||||||
}
|
|
||||||
}, 100);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 页面加载完成后开始异步加载
|
// 页面加载完成后开始异步加载
|
||||||
|
|||||||
Reference in New Issue
Block a user