feat(pdf-viewer): add postinstall script for pdfjs worker and simplify pdf rendering
This commit is contained in:
@@ -1,15 +1,13 @@
|
||||
import React, { useState, useEffect, useRef } from 'react';
|
||||
// 使用 pdf.js 在左侧容器中渲染 PDF 页面,支持自由滑动与页码定位
|
||||
import * as pdfjsLib from 'pdfjs-dist';
|
||||
// 使用 Vite 的资源 URL 解析,将 pdf.js 的模块 worker 转成可访问 URL
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
import pdfjsWorkerUrl from 'pdfjs-dist/build/pdf.worker.min.mjs?url';
|
||||
|
||||
// 采用模块 Worker,避免经典 worker 的 MIME/路径问题
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
const PDFJS_WORKER_MJS = '/pdfjs-dist/pdf.worker.min.mjs';
|
||||
// @ts-ignore
|
||||
pdfjsLib.GlobalWorkerOptions.workerPort = new Worker(pdfjsWorkerUrl, { type: 'module' });
|
||||
pdfjsLib.GlobalWorkerOptions.workerSrc = PDFJS_WORKER_MJS;
|
||||
// @ts-ignore
|
||||
pdfjsLib.GlobalWorkerOptions.disableWorker = true;
|
||||
|
||||
import { useSearchParams } from "react-router-dom";
|
||||
import {
|
||||
Box,
|
||||
@@ -161,17 +159,11 @@ function ChunkParsedResult() {
|
||||
}
|
||||
try {
|
||||
const arrayBuffer = await documentFile.arrayBuffer();
|
||||
const container = pdfContainerRef.current;
|
||||
if (!container) return;
|
||||
|
||||
const renderWithDoc = async (disableWorker: boolean) => {
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
const task = pdfjsLib.getDocument({ data: arrayBuffer, disableWorker });
|
||||
const pdfDoc = await task.promise;
|
||||
|
||||
const container = pdfContainerRef.current;
|
||||
if (!container) return;
|
||||
const renderPages = async (pdfDoc: any) => {
|
||||
container.innerHTML = '';
|
||||
|
||||
// 根据容器宽度自适应缩放
|
||||
const containerRect = container.getBoundingClientRect();
|
||||
const containerWidth = Math.max(1, Math.floor(containerRect.width || container.clientWidth || 800));
|
||||
@@ -215,23 +207,26 @@ function ChunkParsedResult() {
|
||||
}
|
||||
};
|
||||
|
||||
// 尝试使用 Worker(优先模块,其次经典)
|
||||
try {
|
||||
// 优先使用 Worker 渲染
|
||||
await renderWithDoc(false);
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
const task = pdfjsLib.getDocument({ data: arrayBuffer });
|
||||
const pdfDoc = await task.promise;
|
||||
await renderPages(pdfDoc);
|
||||
setPdfRendered(true);
|
||||
} catch (err1) {
|
||||
console.error('PDF.js Worker 渲染失败,降级为主线程渲染。错误: ', err1);
|
||||
try {
|
||||
// Worker 不可用时,禁用 Worker 在主线程渲染
|
||||
await renderWithDoc(true);
|
||||
setPdfRendered(true);
|
||||
} catch (err2) {
|
||||
console.error('PDF.js 主线程渲染失败: ', err2);
|
||||
setPdfRendered(false);
|
||||
}
|
||||
console.error('第一次渲染失败,尝试主线程渲染:', err1);
|
||||
// 失败则回退主线程
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
const fallbackTask = pdfjsLib.getDocument({ data: arrayBuffer, disableWorker: true });
|
||||
const pdfDoc2 = await fallbackTask.promise;
|
||||
await renderPages(pdfDoc2);
|
||||
setPdfRendered(true);
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('读取 PDF 文件数据失败: ', err);
|
||||
console.error('渲染 PDF 过程中发生错误: ', err);
|
||||
setPdfRendered(false);
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user