在现代Web应用开发中,直接在客户端处理PDF文件的需求日益增长,尤其是需要从这些文件中提取文本内容以进行展示、分析或进一步处理的场景。利用JavaScript在React框架下实现PDF文本提取,不仅可以增强用户体验,还能有效减少服务器端的负载压力,提升数据处理的即时性与效率。此方法使得开发者能够构建出更加动态和响应迅速的应用程序,用户无需等待服务器响应即可快速获取所需信息。本文将介绍如何使用JavaScript在React中实现提取PDF文档的文本

  • JavaScript提取PDF文本的操作步骤
  • 用JavaScript保留布局提取PDF文本
  • 用JavaScript提取PDF文本并去除空白
  • 用JavaScript提取PDF页面制定区域的文本
  • 用JavaScript提取PDF中强调显示的文本

本文所使用的方法需要用到Spire.PDF for JavaScript,NPM:npm install spire.pdf

JavaScript提取PDF文本的操作步骤

我们可以使用库中提供的WebAssembly模块来处理PDF文档,模块中提供了一个PdfTextExtractor来轻松完成PDF文档的文字提取任务。以下是使用该库提取PDF文档的一般操作步骤:

  1. 初始化 WebAssembly 环境
    加载 Spire.Pdf.Base.js 文件,并初始化 WebAssembly 模块。
  2. 加载 PDF 文件
    使用 wasmModule.FetchFileToVFS() 方法,将 PDF 文件存入虚拟文件系统(VFS)。
  3. 创建 PDF 文档对象
    先调用 wasmModule.PdfDocument.Create() 方法创建 PdfDocument 实例,然后通过 PdfDocument.LoadFromFile() 方法,从 VFS 加载 PDF 文档。
  4. 设置文本提取参数
    使用 wasmModule.PdfTextExtractOptions.Create() 方法,创建 PdfTextExtractOptions 实例,并配置提取选项。
  5. 获取 PDF 页面
    通过 PdfDocument.Pages.get_Item() 方法或遍历 Pages 集合,获取需要处理的页面对象。
  6. 创建文本提取器
    使用 wasmModule.PdfTextExtractor.Create() 方法,基于页面对象创建 PdfTextExtractor 实例。
  7. 提取文本
    调用 PdfTextExtractor.ExtractText() 方法,从页面中获取文本内容。
  8. 处理或导出文本
    视需求处理提取的文本,或将其下载到本地。

其中,PdfTextExtractOptions提供了IsSimpleExtractionIsExtractAllTextExtractAreaIsShowHiddenText属性来帮助进行各种定制化的文本提取需求。

用JavaScript保留布局提取PDF文本

直接使用PdfTextExtractor.ExtractText()方法通过默认选项提取PDF页面文本时,会提取页面所有文本,并保留空白部分从而保持文本布局不变。
代码示例:

import React, { useState, useEffect } from 'react';

function App() {

  // 用于存储加载的WASM模块的状态
  const [wasmModule, setWasmModule] = useState(null);

  // 使用useEffect钩子在组件挂载时加载WASM模块
  useEffect(() => {
    const loadWasm = async () => {
      try {
        // 从全局window对象中访问Module和spirepdf
        const { Module, spirepdf } = window;

        // 在运行时初始化时设置wasmModule状态
        Module.onRuntimeInitialized = () => {
          setWasmModule(spirepdf);
        };
      } catch (err) {
        // 记录加载模块时发生的任何错误
        console.error('加载WASM模块失败:', err);
      }
    };

    // 创建一个脚本元素来加载WASM JavaScript文件
    const script = document.createElement('script');
    script.src = `${process.env.PUBLIC_URL}/Spire.Pdf.Base.js`;
    script.onload = loadWasm;

    // 将脚本添加到文档的body中
    document.body.appendChild(script);

    // 清理函数:当组件卸载时移除脚本
    return () => {
      document.body.removeChild(script);
    };
  }, []);

  // 从PDF文档中提取所有文本的函数
  const ExtractPDFText = async () => {
    if (wasmModule) {
      // 指定输入和输出文件名
      const inputFileName = 'Sample.pdf';
      const outputFileName = 'PDFTextWithLayout.txt';

      // 获取输入文件并将其添加到VFS
      await wasmModule.FetchFileToVFS(inputFileName, '', `${process.env.PUBLIC_URL}/`);

      // 创建PdfDocument类的实例
      const pdf = wasmModule.PdfDocument.Create();

      // 从VFS加载PDF文档
      pdf.LoadFromFile(inputFileName);

      // 创建一个字符串对象来存储提取的文本
      let text = '';

      // 创建PdfTextExtractOptions类的实例
      const extractOptions = wasmModule.PdfTextExtractOptions.Create();

      // 遍历PDF文档的每一页
      for (let i = 0; i < pdf.Pages.Count; i++) {
        // 获取当前页面
        const page = pdf.Pages.get_Item(i);
        // 创建PdfTextExtractor类的实例
        const textExtractor = wasmModule.PdfTextExtractor.Create(page);
        // 从当前页面提取文本并将其添加到文本字符串中
        text += textExtractor.ExtractText(extractOptions);
      }

      // 从文本字符串创建Blob对象并下载
      const blob = new Blob([text], { type: 'text/plain' });
      const url = URL.createObjectURL(blob);
      const a = document.createElement('a');
      a.href = url;
      a.download = `${outputFileName}`;
      document.body.appendChild(a);
      a.click();
      document.body.removeChild(a);
      URL.revokeObjectURL(url);
    }
  };

  return (
      <div style={{ textAlign: 'center', height: '300px' }}>
        <h1>使用JavaScript在React中从PDF提取文本</h1>
        <button onClick={ExtractPDFText} disabled={!wasmModule}>
          提取并下载
        </button>
      </div>
  );
}

export default App;

提取结果
JavaScript提取PDF文本保留布局

用JavaScript提取PDF文本并去除空白

我们将PdfTextExtractOptions类的IsSimpleExtraction属性设置为true时,提取结果的文本将会去除多余的空白而不保留文本布局。此方法可以方便需要对提取的文本进行进一步操作的场景,去除多余空白的干扰。
代码示例:

import React, { useState, useEffect } from 'react';

function App() {

  // 用于存储加载的WASM模块的状态
  const [wasmModule, setWasmModule] = useState(null);

  // 使用useEffect钩子在组件挂载时加载WASM模块
  useEffect(() => {
    const loadWasm = async () => {
      try {
        // 从全局window对象中访问Module和spirepdf
        const { Module, spirepdf } = window;

        // 在运行时初始化时设置wasmModule状态
        Module.onRuntimeInitialized = () => {
          setWasmModule(spirepdf);
        };
      } catch (err) {
        // 记录加载模块时发生的任何错误
        console.error('加载WASM模块失败:', err);
      }
    };

    // 创建一个脚本元素来加载WASM JavaScript文件
    const script = document.createElement('script');
    script.src = `${process.env.PUBLIC_URL}/Spire.Pdf.Base.js`;
    script.onload = loadWasm;

    // 将脚本添加到文档的body中
    document.body.appendChild(script);

    // 清理函数:当组件卸载时移除脚本
    return () => {
      document.body.removeChild(script);
    };
  }, []);

  // 从PDF文档中提取文本(不保留布局)的函数
  const ExtractPDFText = async () => {
    if (wasmModule) {
      // 指定输入和输出文件名
      const inputFileName = 'Sample.pdf';
      const outputFileName = 'PDFTextWithoutLayout.txt';

      // 获取输入文件并将其添加到VFS
      await wasmModule.FetchFileToVFS(inputFileName, '', `${process.env.PUBLIC_URL}/`);

      // 创建PdfDocument类的实例
      const pdf = wasmModule.PdfDocument.Create();

      // 从VFS加载PDF文档
      pdf.LoadFromFile(inputFileName);

      // 创建一个字符串对象来存储提取的文本
      let text = '';

      // 创建PdfTextExtractOptions类的实例
      const extractOptions = wasmModule.PdfTextExtractOptions.Create();

      // 启用简单文本提取模式,不保留文本布局
      extractOptions.IsSimpleExtraction = true;

      // 遍历PDF文档的每一页
      for (let i = 0; i < pdf.Pages.Count; i++) {
        // 获取当前页面
        const page = pdf.Pages.get_Item(i);
        // 创建PdfTextExtractor类的实例
        const textExtractor = wasmModule.PdfTextExtractor.Create(page);
        // 从当前页面提取文本并将其添加到文本字符串中
        text += textExtractor.ExtractText(extractOptions);
      }

      // 从文本字符串创建Blob对象并下载
      const blob = new Blob([text], { type: 'text/plain' });
      const url = URL.createObjectURL(blob);
      const a = document.createElement('a');
      a.href = url;
      a.download = `${outputFileName}`;
      document.body.appendChild(a);
      a.click();
      document.body.removeChild(a);
      URL.revokeObjectURL(url);
    }
  };

  return (
      <div style={{ textAlign: 'center', height: '300px' }}>
        <h1>使用JavaScript在React中从PDF提取文本(不保留布局)</h1>
        <button onClick={ExtractPDFText} disabled={!wasmModule}>
          提取并下载
        </button>
      </div>
  );
}

export default App;

结果
JavaScript提取PDF文本去除空白

用JavaScript提取PDF页面制定区域的文本

PdfTextExtractOptions类的ExtractArea属性可以通过一个RectangleF对象对提取区域进行设置,提取时将只提取页面上矩形区域的文本,从而方便提取时避免提取到页面固定的重复内容。
代码示例:

import React, { useState, useEffect } from 'react';

function App() {

  // 用于存储加载的WASM模块的状态
  const [wasmModule, setWasmModule] = useState(null);

  // 使用useEffect钩子在组件挂载时加载WASM模块
  useEffect(() => {
    const loadWasm = async () => {
      try {
        // 从全局window对象中访问Module和spirepdf
        const { Module, spirepdf } = window;

        // 在运行时初始化时设置wasmModule状态
        Module.onRuntimeInitialized = () => {
          setWasmModule(spirepdf);
        };
      } catch (err) {
        // 记录加载模块时发生的任何错误
        console.error('加载WASM模块失败:', err);
      }
    };

    // 创建一个脚本元素来加载WASM JavaScript文件
    const script = document.createElement('script');
    script.src = `${process.env.PUBLIC_URL}/Spire.Pdf.Base.js`;
    script.onload = loadWasm;

    // 将脚本添加到文档的body中
    document.body.appendChild(script);

    // 清理函数:当组件卸载时移除脚本
    return () => {
      document.body.removeChild(script);
    };
  }, []);

  // 从PDF页面的特定区域提取文本的函数
  const ExtractPDFText = async () => {
    if (wasmModule) {
      // 指定输入和输出文件名
      const inputFileName = 'Sample.pdf';
      const outputFileName = 'PDFTextPageArea.txt';

      // 获取输入文件并将其添加到VFS
      await wasmModule.FetchFileToVFS(inputFileName, '', `${process.env.PUBLIC_URL}/`);

      // 创建PdfDocument类的实例
      const pdf = wasmModule.PdfDocument.Create();

      // 从VFS加载PDF文档
      pdf.LoadFromFile(inputFileName);

      // 创建一个字符串对象来存储提取的文本
      let text = '';

      // 获取PDF文档中的某一页
      const page = pdf.Pages.get_Item(0);

      // 创建PdfTextExtractOptions类的实例
      const extractOptions = wasmModule.PdfTextExtractOptions.Create();

      // 设定要提取文本的页面区域,使用RectangleF对象
      extractOptions.ExtractArea = wasmModule.RectangleF.Create({ x: 0, y: 500, width: page.Size.Width, height: 200 });

      // 创建PdfTextExtractor类的实例
      const textExtractor = wasmModule.PdfTextExtractor.Create(page);

      // 从指定区域提取文本
      text = textExtractor.ExtractText(extractOptions);

      // 从文本字符串创建Blob对象并下载
      const blob = new Blob([text], { type: 'text/plain' });
      const url = URL.createObjectURL(blob);
      const a = document.createElement('a');
      a.href = url;
      a.download = `${outputFileName}`;
      document.body.appendChild(a);
      a.click();
      document.body.removeChild(a);
      URL.revokeObjectURL(url);
    }
  };

  return (
      <div style={{ textAlign: 'center', height: '300px' }}>
        <h1>使用JavaScript在React中从PDF页面的特定区域提取文本</h1>
        <button onClick={ExtractPDFText} disabled={!wasmModule}>
          提取并下载
        </button>
      </div>
  );
}

export default App;

结果
JavaScript提取PDF页面指定位置的文本

用JavaScript提取PDF中强调显示的文本

由于PDF文档中的文字强调功能是通过添加注释实现的,我们可以使用库中的PdfPageBase.Annotations获取PDF页面上的所有注释,并找出为PdfTextMarkupAnnotationWidget实例的注释,从而找出文本强调注释。然后,我们可以使用Bounds属性获取文本强调注释所在的区域,并将其设置为文本提取区域,从而对强调显示的文本进行提取。
代码示例:

import React, { useState, useEffect } from 'react';

function App() {

  // 用于存储加载的WASM模块的状态
  const [wasmModule, setWasmModule] = useState(null);

  // 使用useEffect钩子在组件挂载时加载WASM模块
  useEffect(() => {
    const loadWasm = async () => {
      try {
        // 从全局window对象中访问Module和spirepdf
        const { Module, spirepdf } = window;

        // 在运行时初始化时设置wasmModule状态
        Module.onRuntimeInitialized = () => {
          setWasmModule(spirepdf);
        };
      } catch (err) {
        // 记录加载模块时发生的任何错误
        console.error('加载WASM模块失败:', err);
      }
    };

    // 创建一个脚本元素来加载WASM JavaScript文件
    const script = document.createElement('script');
    script.src = `${process.env.PUBLIC_URL}/Spire.Pdf.Base.js`;
    script.onload = loadWasm;

    // 将脚本添加到文档的body中
    document.body.appendChild(script);

    // 清理函数:当组件卸载时移除脚本
    return () => {
      document.body.removeChild(script);
    };
  }, []);

  // 从PDF中提取高亮文本的函数
  const ExtractPDFText = async () => {
    if (wasmModule) {
      // 指定输入和输出文件名
      const inputFileName = 'Sample.pdf';
      const outputFileName = 'PDFTextHighlighted.txt';

      // 获取输入文件并将其添加到VFS
      await wasmModule.FetchFileToVFS(inputFileName, '', `${process.env.PUBLIC_URL}/`);

      // 创建PdfDocument类的实例
      const pdf = wasmModule.PdfDocument.Create();

      // 从VFS加载PDF文档
      pdf.LoadFromFile(inputFileName);

      // 创建一个字符串对象来存储提取的文本
      let text = '';

      // 遍历PDF文档的每一页
      for (const page of pdf.Pages) {
        // 遍历当前页面的所有注释
        for (let i = 0; i < page.Annotations.Count; i++) {
          // 获取当前注释
          const annotation = page.Annotations.get_Item(i);
          // 检查该注释是否是PdfTextMarkupAnnotation的实例(高亮标注)
          if (annotation instanceof wasmModule.PdfTextMarkupAnnotationWidget) {
            // 获取高亮注释的边界
            const bounds = annotation.Bounds;
            // 创建PdfTextExtractOptions的实例
            const extractOptions = wasmModule.PdfTextExtractOptions.Create();
            // 设置高亮注释的边界为文本提取区域
            extractOptions.ExtractArea = bounds;
            // 创建PdfTextExtractor类的实例
            const textExtractor = wasmModule.PdfTextExtractor.Create(page);
            // 提取高亮文本并追加到text字符串中
            text += textExtractor.ExtractText(extractOptions);
          }
        }
      }

      // 从文本字符串创建Blob对象并下载
      const blob = new Blob([text], { type: 'text/plain' });
      const url = URL.createObjectURL(blob);
      const a = document.createElement('a');
      a.href = url;
      a.download = `${outputFileName}`;
      document.body.appendChild(a);
      a.click();
      document.body.removeChild(a);
      URL.revokeObjectURL(url);
    }
  };

  return (
      <div style={{ textAlign: 'center', height: '300px' }}>
        <h1>使用JavaScript在React中提取PDF中的高亮文本</h1>
        <button onClick={ExtractPDFText} disabled={!wasmModule}>
          提取并下载
        </button>
      </div>
  );
}

export default App;

结果
JavaScript提取PDF强调文本

本文演示了如何使用JavaScript在React提取PDF文本,以及如何进行各种提取选项的定制。


大丸子
72 声望6 粉丝