You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pdfjs-dist在Next.js14 App Router(JS)中提取PDF文本报错的解决方法

问题修复方案

核心错误原因

你遇到的「Element type is invalid」错误,根源在于使用异步函数作为filter的回调:

  • filter需要同步返回布尔值,但异步函数会返回Promise,导致pdf_files变成一个Promise数组而非文本内容数组。如果后续尝试在JSX中渲染这个数组,React会因收到Promise而非有效元素/文本而抛出错误。

此外代码中还有几处关键问题:

  1. Worker配置错误:pdfjs.GlobalWorkerOptions.workerSrc需要的是Worker脚本的URL,而非导入的模块对象
  2. 冗余的await:doc已经是await后的结果,无需再次await doc
  3. 变量名错误:pdf.getPage(i)应为doc.getPage(i)
  4. 低效的Blob URL创建:pdfjs支持直接传入ArrayBuffer,无需转成Blob URL

修正后的完整代码(Next.js 14 客户端组件)

'use client';

import * as pdfjs from "pdfjs-dist/build/pdf.mjs";
// 用?url后缀让Next.js返回Worker脚本的URL字符串
import workerUrl from "pdfjs-dist/build/pdf.worker.mjs?url";

// 初始化pdfjs Worker
pdfjs.GlobalWorkerOptions.workerSrc = workerUrl;

export default function PDFTextExtractor() {
  const handleFileSelect = async (e) => {
    const files = Array.from(e.target.files);

    // 单独封装PDF文本提取逻辑
    const extractTextFromPDF = async (file) => {
      if (file.type !== "application/pdf") return null;

      const arrayBuffer = await file.arrayBuffer();
      // 直接传入ArrayBuffer给pdfjs,无需Blob URL
      const doc = await pdfjs.getDocument({ data: arrayBuffer }).promise;

      let allText = "";
      const numPages = doc.numPages;

      for (let i = 1; i <= numPages; i++) {
        const page = await doc.getPage(i);
        const content = await page.getTextContent();
        // 给文本项之间添加空格,提升可读性
        const pageText = content.items.map(item => item.str).join(" ");
        allText += pageText + "\n\n"; // 页面间添加换行分隔
      }

      return { filename: file.name, text: allText };
    };

    // 用Promise.all批量处理所有文件,过滤掉非PDF的结果
    const results = await Promise.all(files.map(extractTextFromPDF));
    const pdfTexts = results.filter(result => result !== null);

    // 这里可以处理提取后的文本,比如存入状态用于渲染
    console.log("提取的PDF文本:", pdfTexts);
    // setExtractedTexts(pdfTexts); // 若需渲染,可设置状态
  };

  return (
    <div>
      <input 
        type="file" 
        multiple 
        accept="application/pdf" 
        onChange={handleFileSelect} 
      />
      {/* 可在此处渲染提取后的文本,例如:
      {pdfTexts.map((item, idx) => (
        <div key={idx}>
          <h3>{item.filename}</h3>
          <pre>{item.text}</pre>
        </div>
      ))}
      */}
    </div>
  );
}

关键修正点说明

  1. Worker配置:通过pdf.worker.mjs?url导入Worker脚本的URL,符合pdfjs对workerSrc的要求
  2. 异步处理逻辑:用map + Promise.all替代filter,正确批量处理异步文件提取
  3. 代码精简:直接传入ArrayBuffer给getDocument,省去Blob和URL创建步骤
  4. 变量修正:修复pdf.getPage的变量名错误,移除冗余的await

内容的提问来源于stack exchange,提问作者Coder

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 20:35:58