🌊
【PDF.js】ReactでPDF.jsを使ってPDFテキストを抽出したい
背景
業務でPDF.jsを使用してPDFテキストを抽出する機能を作成しましたので、PDF.jsのお作法や詰まったところを書き連ねていきます。
動作環境
- React 18.3.1
- Typescript 5.5.3
- PDF.js 4.8.69
- yarn 4.4.1
基本
インストール
yarn add -D pdfjs-dist
PDF.js ワーカーの設定
import * as pdfjsLib from "pdfjs-dist";
pdfjsLib.GlobalWorkerOptions.workerSrc = new URL(
"pdfjs-dist/build/pdf.worker.min.mjs",
import.meta.url,
).toString();
PDFの読み込み
const pdfData = await selectedPdf.arrayBuffer();
const loadingTask = pdfjsLib.getDocument({
data: pdfData, // ArrayBuffer型である必要がある
verbosity: 1,
});
- verbosity:PDF.js のデバッグログの出力レベル。
- 0:ログ出力を無効化(デフォルト)。エラーや警告メッセージは表示されません。
- 1:エラーのみを表示。PDF.js の動作に影響を与える重大な問題のみがログに記録されます。
- 2:エラーと警告を表示。PDF.js の動作に影響を与える可能性がある問題も記録されます。
- 3:エラー、警告、情報メッセージをすべて表示。詳細なデバッグ情報が得られます(開発時向け)。
応用
PDFのページ数を取得する
const loadingTask = pdfjsLib.getDocument({
data: pdfData,
verbosity: 1,
});
const pdf = await loadingTask.promise;
const maxPages = pdf.numPages;
PDFテキストを取得する
let pdfText = "";
const page = await pdf.getPage(pageNumber); // 取得したいページ数を引数に指定
const { items } = await page.getTextContent({
includeMarkedContent: true,
});
const pageText = items
.map((item) => {
return "str" in item ? (item.hasEOL ? "\n" : item.str) : "";
})
.join("");
pdfText += pageText + "\n";
-
hasEOL
(boolean):改行コードの場合、trueになる -
str
:格納している文字- 一文字ずつ格納されているので注意
- 区切り文字が何なのかはわかってないです🙇
- 一文字ずつ格納されているので注意
全てのページのテキストを取得する
const loadingTask = pdfjsLib.getDocument({
data: pdfData,
verbosity: 0,
});
const pdf = await loadingTask.promise;
const maxPages = pdf.numPages;
let pdfText = "";
// テキスト抽出
for (let pageNumber = 1; pageNumber <= maxPages; pageNumber++) {
const page = await pdf.getPage(pageNumber);
const { items } = await page.getTextContent({
includeMarkedContent: true,
});
const pageText = items
.map((item) => {
return "str" in item ? (item.hasEOL ? "\n" : item.str) : "";
})
.join("");
pdfText += pageText + "\n";
}
実務で詰まったところ
PDF.js ワーカーの設定
import * as pdfjs from 'pdfjs-dist/legacy/build/pdf';
import * as pdfjsWorker from 'pdfjs-dist/legacy/build/pdf.worker.entry';
pdfjs.GlobalWorkerOptions.workerSrc = pdfjsWorker;
ネットの記事を見ているが上記のようにワーカーを設定しているが、
実際pdfjs-dist/legacy/build/pdf.worker.entry
のモジュールを読み込めない。
バージョンアップして読み込み方が変わったのかな??
Warning: TT: undefined function: 3 の解決方法
エラー表示条件:PDFテキスト内に解析できないフォントが存在する場合
なんと解決方法はない。(解決しなくていい?)
getDocumentのverbosityを0に指定すれば表示されない。
参考にした記事
Discussion