我一直在使用这些帖子中的代码改编版:
pdfjs:使用正确的换行符/空格从 pdf 中获取原始文本
将 pdf 文件转换为文本:
import pdfjsLib from 'pdfjs-dist/legacy/build/pdf.js';
import {
TextItem,
DocumentInitParameters,
} from 'pdfjs-dist/types/src/display/api';
const getPageText = async (pdf: pdfjsLib.PDFDocumentProxy, pageNo: number) => {
const page = await pdf.getPage(pageNo);
const tokenizedText = await page.getTextContent();
var textItems = tokenizedText.items;
var finalString = '';
var line = 0;
// Concatenate the string of the item to the final string
for (var i = 0; i < textItems.length; i++) {
if (line != (textItems[i] as TextItem).transform[5]) {
if (line != 0) {
finalString += '\r\n';
}
line = (textItems[i] as TextItem).transform[5];
}
var item = textItems[i];
finalString += (item as TextItem).str;
}
return finalString;
};
export const getPDFText = async (
data: string,
password: string | undefined = undefined
) => {
const initParams: DocumentInitParameters = {
data: Buffer.from(data, 'base64'),
//useSystemFonts: true,
//disableFontFace: false,
standardFontDataUrl: 'standard_fonts/'
};
if (password !== undefined) {
initParams.password = password;
}
const pdf = await pdfjsLib.getDocument(initParams).promise;
const maxPages = pdf.numPages;
const pageTextPromises = [];
for (let pageNo = 1; pageNo <= maxPages; pageNo += 1) {
pageTextPromises.push(getPageText(pdf, pageNo));
}
const pageTexts = await Promise.all(pageTextPromises);
const joined = pageTexts.join(' ');
return joined;
};
使用 pdfjs-dist 3.1.81 版本,这看起来相当不错,但表单字段上的复选框丢失了,文本字段的值显示在每个页面的末尾,而不是保留在上下文中。我觉得这个页面:https://pdftotext.com/基于与我的输出的相似性使用pdfjs,但他们在方框上进行了检查,并且他们的文本字段“答案”是问题。
运行:
import { join } from 'path';
import { readFileSync } from 'fs';
const rawContents = readFileSync(join('directory', 'file.pdf'), 'base64');
const pdfText = await getPDFText(rawContents as string);
有人知道我为什么会丢失支票(盒子就在那里)吗?
我得到的样本:
22. when something something?
☐ 0-3 months ago
☐ 4-6 months ago
☐ 7-12 months ago
☐ 13-18 months ago
☐ 19-24 months ago
☐ 25-60 months ago
☐ I don't know
该网页得到的内容如下:
22. when something something?
✔ 0-3 months ago
☐
☐ 4-6 months ago
☐ 7-12 months ago
☐ 13-18 months ago
☐ 19-24 months ago
☐ 25-60 months ago
☐ I don’t know
再次,我的输出看起来像他们的,但丢失了这些检查。我不确定他们是否使用 pdfjs,但我认为他们确实使用了。
请注意,我已经下载了一些字体并将其放在 standard_fonts 目录中。即使我没有看到警告消息,我是否应该将它们全部复制?
在表单中,复选框是字段边界,不属于任何附近文本的一部分(所有字段都是如此,它们不直接连接到其描述),它们仅具有名称和值。这里放置了 Check Box1 和 Box2,Box3 正在等待表面外观。
特别注意,它们的外观并不固定,它们在展示时会变形,它们是嵌合体,看起来就像存在一样。
在这些 AcroForm 情况下,它们没有本地纯文本等价物,没有任何东西可以检测索引只是指向页面坐标。
PDF.js 是一个 PDF2HTML 转换器,因此可以轻松地将这些索引区域显示为 html 字段。 注意它是一个X。
就 PDF 可提取表面而言,没有文本,我们可以看到上面和下面的框只有在这些单选框旁边看到的描述
注意这是一个勾号。除了显示器(查看器)之外没有什么不同
如果我们尝试使用 PDF.js(此处在浏览器中)提取文本,我们只会得到文本
在某些情况下,Symbol 或 ZapfDingbats 原生字体或其他具有这些代码点的 TTF 已被嵌入并适应状态,可能会获得带字体的复选标记符号,但这种情况很少见,除非专门设计。
☐ 如您在案例中看到的那样,然后替换为一个
☑ 正在从字体中选择正确的字体并添加为
☒ 更换不是很容易但可行。
因此,可以使用简单的 pdftotext 或 Python 再次提取通过 HTML 打印为 PDF 的上述符号。
☐ as you see in your case then to replace with one
☑ is picking the correct one from font and add as
☒ replacement it's not very easy but doable.
对于其他正在寻找的人:
https://formulae.brew.sh/formula/poppler
这包括
pdftotext
获得复选标记的命令
编辑 经过进一步研究,我绝对喜欢 poppler 的 pdftotext。它确实有一个奇怪之处,即包裹在破折号上的线将被展开减去破折号。我认为它试图变得聪明并假设破折号在那里表示换行。几乎是一个边缘情况,但值得注意。
还有一个节点包装器,可以让您不必处理临时文件:https://www.npmjs.com/package/node-pdftotext