由于 PDF 文件是一个二进制文件,直接读取头部并提取信息是比较复杂的。你可以通过 FileReader 读取 PDF 文件的前几百字节,然后通过解析这些字节,获取 PDF 的元数据。
使用 FileReader 读取 PDF 文件
读取 PDF 文件头部的前 1024 字节。
解析 PDF 文档信息,手动从文本中查找关键字段。
<input type="file" id="pdfInput" accept=".pdf" />
<pre id="output"></pre>
<script>
document.getElementById('pdfInput').addEventListener('change', function (event) {
const file = event.target.files[0];
if (!file) return;
const reader = new FileReader();
reader.onload = function () {
const arrayBuffer = this.result;
const uint8Array = new Uint8Array(arrayBuffer);
// 将字节转换为字符串
const pdfText = new TextDecoder('utf-8').decode(uint8Array);
// 尝试解析 PDF 的基本信息
const metadata = extractPdfMetadata(pdfText);
document.getElementById('output').textContent = JSON.stringify(metadata, null, 2);
};
// 读取前 1024 字节
reader.readAsArrayBuffer(file.slice(0, 1024));
});
function extractPdfMetadata(text) {
const metadata = {};
const titleMatch = text.match(/\/Title\s*\((.*?)\)/);
const authorMatch = text.match(/\/Author\s*\((.*?)\)/);
const subjectMatch = text.match(/\/Subject\s*\((.*?)\)/);
const creatorMatch = text.match(/\/Creator\s*\((.*?)\)/);
const producerMatch = text.match(/\/Producer\s*\((.*?)\)/);
const creationDateMatch = text.match(/\/CreationDate\s*\((.*?)\)/);
const modDateMatch = text.match(/\/ModDate\s*\((.*?)\)/);
// 提取 PDF 元数据
metadata.title = titleMatch ? titleMatch[1] : 'Unknown';
metadata.author = authorMatch ? authorMatch[1] : 'Unknown';
metadata.subject = subjectMatch ? subjectMatch[1] : 'Unknown';
metadata.creator = creatorMatch ? creatorMatch[1] : 'Unknown';
metadata.producer = producerMatch ? producerMatch[1] : 'Unknown';
metadata.creationDate = creationDateMatch ? creationDateMatch[1] : 'Unknown';
metadata.modDate = modDateMatch ? modDateMatch[1] : 'Unknown';
return metadata;
}
</script>
代码解析
FileReader 读取文件:当用户选择文件后,FileReader 读取 PDF 文件的前 1024 字节。
TextDecoder 解析字节流:使用 TextDecoder 将二进制数据转换为可读的字符串。
解析 PDF 元数据:手动通过正则表达式查找关键字段(如 Title、Author 等)并提取值。
显示元数据:将提取的信息显示在页面中。
这种方法的局限性
不稳定性:PDF 文件的格式并不统一,特别是不同软件生成的 PDF 结构可能大不相同。
缺乏深度解析:该方法只能读取最基本的元数据,无法解析 PDF 的内容或处理复杂的加密文件。
易受编码影响:PDF 文件可能包含不同的字符编码,使用简单的 TextDecoder 并不能保证所有字符正确解码。
总结
虽然可以通过浏览器原生的方法读取 PDF 文件并获取一些基本的元数据,但这种方法并不如使用专业的 PDF 库(如 PDF.js 或 pdf-lib)稳定和可靠。对于简单的应用场景,这种方法可以作为参考,但不推荐用于生产环境。更可靠的方式是使用专门的 PDF 解析库来处理文档的读取和元数据提取。
pdf-lib
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdf-lib/1.17.1/pdf-lib.min.js"></script>
<script>
document.getElementById('pdfInput').addEventListener('change', async function (event) {
const file = event.target.files[0];
if (!file) return;
// 读取文件
const reader = new FileReader();
reader.onload = async function () {
const arrayBuffer = this.result;
// 加载 PDF 文档
const pdfDoc = await PDFLib.PDFDocument.load(arrayBuffer);
// 获取 PDF 元数据
const info = pdfDoc.getTitle()
? {
title: await pdfDoc.getTitle(),
author: await pdfDoc.getAuthor(),
subject: await pdfDoc.getSubject(),
creator: await pdfDoc.getCreator(),
producer: await pdfDoc.getProducer(),
creationDate: pdfDoc.getCreationDate(),
modificationDate: pdfDoc.getModificationDate(),
}
: 'No metadata available';
// 显示 PDF 元数据
document.getElementById('output').textContent = JSON.stringify(info, null, 2);
};
reader.readAsArrayBuffer(file);
});
</script>