Javascript 如何在JavaSript中从PDF中提取文本
我想知道是否可以只使用Javascript来获取PDF文件中的文本? 如果是,有人能告诉我怎么做吗 我知道有一些服务器端java、c#等库,但我不希望使用服务器。 谢谢这是可能的,但是:Javascript 如何在JavaSript中从PDF中提取文本,javascript,pdf,text,Javascript,Pdf,Text,我想知道是否可以只使用Javascript来获取PDF文件中的文本? 如果是,有人能告诉我怎么做吗 我知道有一些服务器端java、c#等库,但我不希望使用服务器。 谢谢这是可能的,但是: 无论如何,您都必须使用服务器,如果不将文件传输到服务器并返回,就无法在用户计算机上获取文件内容 我认为还没有人写过这样的图书馆 因此,如果您有一些空闲时间,您可以学习pdf格式并自己编写这样的库,或者您当然可以使用服务器端库。以下是一些JavaScript代码,可以实现您使用pdf.js所需的功能: …下面
- 无论如何,您都必须使用服务器,如果不将文件传输到服务器并返回,就无法在用户计算机上获取文件内容
- 我认为还没有人写过这样的图书馆
因此,如果您有一些空闲时间,您可以学习pdf格式并自己编写这样的库,或者您当然可以使用服务器端库。以下是一些JavaScript代码,可以实现您使用pdf.js所需的功能: …下面是一个例子:
这是一个古老的问题,但由于pdf.js多年来一直在发展,我想给出一个新的答案。也就是说,它可以在本地完成,而不涉及任何服务器或外部服务。新的pdf.js有一个函数:page.getTextContent()。您可以从中获取文本内容。我已经用下面的代码成功地完成了它
。然后(function(){…})
继续下一步
1) PDFJS.getDocument(数据)。然后(函数(pdf){
2) pdf.getPage(i).then(函数(页面){
3) page.getTextContent().then(函数(textContent){
textContent.bidiTexts[]
。您将它们连接起来以获得1页的文本。文本块的坐标用于判断是否需要插入换行符或空格。(这可能不完全可靠,但从我的测试来看似乎还可以。)data
需要是URL或ArrayBuffer类型的数据。我使用FileReader
API中的ReadAsArrayBuffer(文件)函数来获取数据textContent.bidiTexts
替换为textContent.items
function Pdf2TextClass(){
var self = this;
this.complete = 0;
/**
*
* @param data ArrayBuffer of the pdf file content
* @param callbackPageDone To inform the progress each time
* when a page is finished. The callback function's input parameters are:
* 1) number of pages done;
* 2) total number of pages in file.
* @param callbackAllDone The input parameter of callback function is
* the result of extracted text from pdf file.
*
*/
this.pdfToText = function(data, callbackPageDone, callbackAllDone){
console.assert( data instanceof ArrayBuffer || typeof data == 'string' );
PDFJS.getDocument( data ).then( function(pdf) {
var div = document.getElementById('viewer');
var total = pdf.numPages;
callbackPageDone( 0, total );
var layers = {};
for (i = 1; i <= total; i++){
pdf.getPage(i).then( function(page){
var n = page.pageNumber;
page.getTextContent().then( function(textContent){
if( null != textContent.bidiTexts ){
var page_text = "";
var last_block = null;
for( var k = 0; k < textContent.bidiTexts.length; k++ ){
var block = textContent.bidiTexts[k];
if( last_block != null && last_block.str[last_block.str.length-1] != ' '){
if( block.x < last_block.x )
page_text += "\r\n";
else if ( last_block.y != block.y && ( last_block.str.match(/^(\s?[a-zA-Z])$|^(.+\s[a-zA-Z])$/) == null ))
page_text += ' ';
}
page_text += block.str;
last_block = block;
}
textContent != null && console.log("page " + n + " finished."); //" content: \n" + page_text);
layers[n] = page_text + "\n\n";
}
++ self.complete;
callbackPageDone( self.complete, total );
if (self.complete == total){
window.setTimeout(function(){
var full_text = "";
var num_pages = Object.keys(layers).length;
for( var j = 1; j <= num_pages; j++)
full_text += layers[j] ;
callbackAllDone(full_text);
}, 1000);
}
}); // end of page.getTextContent().then
}); // end of page.then
} // of for
});
}; // end of pdfToText()
}; // end of class
函数Pdf2TextClass(){
var self=这个;
此值为0.complete=0;
/**
*
*pdf文件内容的@param data ArrayBuffer
*@param callbackPageDone每次通知进度
*页面完成时。回调函数的输入参数为:
*1)完成的页数;
*2)文件中的总页数。
*@param callbackAllDone回调函数的输入参数为
*从pdf文件中提取文本的结果。
*
*/
this.pdfToText=函数(数据、callbackPageDone、callbackAllDone){
assert(ArrayBuffer | | typeof data=='string');
getDocument(数据).then(函数)(pdf){
var div=document.getElementById('viewer');
var total=pdf.numPages;
callbackPageDone(0,总计);
var层={};
例如(i=1;i我无法让gm2008的示例正常工作(pdf.js上的内部数据结构显然发生了变化),因此我编写了自己的完全基于承诺的解决方案,它不使用任何DOM元素、QuerySelector或canvas,使用的是在
它会吃掉上传的文件路径,因为我将它与node webkit一起使用。
您需要确保已下载CMAP并指向某个位置,并且需要使用pdf.js和pdf.worker.js才能使其正常工作
/**
* Extract text from PDFs with PDF.js
* Uses the demo pdf.js from https://mozilla.github.io/pdf.js/getting_started/
*/
this.pdfToText = function(data) {
PDFJS.workerSrc = 'js/vendor/pdf.worker.js';
PDFJS.cMapUrl = 'js/vendor/pdfjs/cmaps/';
PDFJS.cMapPacked = true;
return PDFJS.getDocument(data).then(function(pdf) {
var pages = [];
for (var i = 0; i < pdf.numPages; i++) {
pages.push(i);
}
return Promise.all(pages.map(function(pageNumber) {
return pdf.getPage(pageNumber + 1).then(function(page) {
return page.getTextContent().then(function(textContent) {
return textContent.items.map(function(item) {
return item.str;
}).join(' ');
});
});
})).then(function(pages) {
return pages.join("\r\n");
});
});
}
对于所有实际希望在节点服务器上使用它的人:
/**
* Created by velten on 25.04.16.
*/
"use strict";
let pdfUrl = "http://example.com/example.pdf";
let request = require('request');
var pdfParser = require('pdf2json');
let pdfPipe = request({url: pdfUrl, encoding:null}).pipe(pdfParser);
pdfPipe.on("pdfParser_dataError", err => console.error(err) );
pdfPipe.on("pdfParser_dataReady", pdf => {
//optionally:
//let pdf = pdfParser.getMergedTextBlocksIfNeeded();
let count1 = 0;
//get text on a particular page
for (let page of pdf.formImage.Pages) {
count1 += page.Texts.length;
}
console.log(count1);
pdfParser.destroy();
});
注意:此代码假设您使用的是nodejs。这意味着您正在解析本地文件,而不是网页中的文件,因为原始问题没有明确询问解析网页上的PDF
@gm2008的答案是一个很好的起点(请阅读它和它的评论以获取更多信息),但需要一些更新(08/19)和一些未使用的代码。我也喜欢更完整的示例。可以进行更多的重构和调整(例如使用wait
),但现在它尽可能接近原始答案
和以前一样,它使用Mozilla的PDFjs库
根据我的经验,这在找到放置空间的位置方面做得不好,但这是下一次的问题
[编辑:我相信对.transform
使用的更新已将空白恢复为原来的状态。]
//此文件名为mypdffieltotext.js,位于根文件夹中
设PDFJS=require('PDFJS-dist');
让pathToPDF='path/to/mypdffieltotext.pdf';
设toText=Pdf2TextObj();
让onPageDone=function(){};//不希望在页面之间执行任何操作
让onFinish=function(全文){console.log(全文)};
pdfToText(路径topdf、onPageDone、onFinish);
函数Pdf2TextObj(){
让自我=这个;
此值为0.complete=0;
/**
*
*@param path指向pdf文件的路径。
*@param callbackPageDone每次通知进度
*页面完成时。回调函数的输入参数为:
*1)完成的页数。
*2)文件中的总页数。
*3)`page`对象本身或null。
*在收集所有文本后调用@param callbackAllDone。输入参数:
*1)已解析pdf的全文。
*
*/
this.pdfToText=函数(路径、callbackPageDone、callbackAllDone){
//assert(typeof path=='string');
getDocument(path).promise.then(函数)(pdf){
让total=pdf.numPages;
callbackPageDone(0,总计,空);
让pages={};
//出于某些(pdf?)原因,这些并不是连续出现的
//顺序。这就是为什么它们被存储为一个对象,然后
self.pdfToText(files[0].path).then(function(result) {
console.log("PDF done!", result);
})
/**
* Created by velten on 25.04.16.
*/
"use strict";
let pdfUrl = "http://example.com/example.pdf";
let request = require('request');
var pdfParser = require('pdf2json');
let pdfPipe = request({url: pdfUrl, encoding:null}).pipe(pdfParser);
pdfPipe.on("pdfParser_dataError", err => console.error(err) );
pdfPipe.on("pdfParser_dataReady", pdf => {
//optionally:
//let pdf = pdfParser.getMergedTextBlocksIfNeeded();
let count1 = 0;
//get text on a particular page
for (let page of pdf.formImage.Pages) {
count1 += page.Texts.length;
}
console.log(count1);
pdfParser.destroy();
});
<script src="https://npmcdn.com/pdfjs-dist/build/pdf.js"></script>
<script>
function Pdf2TextClass(){
var self = this;
this.complete = 0;
this.pdfToText = function(data, callbackPageDone, callbackAllDone){
console.assert( data instanceof ArrayBuffer || typeof data == 'string' );
var loadingTask = pdfjsLib.getDocument(data);
loadingTask.promise.then(function(pdf) {
var total = pdf._pdfInfo.numPages;
//callbackPageDone( 0, total );
var layers = {};
for (i = 1; i <= total; i++){
pdf.getPage(i).then( function(page){
var n = page.pageNumber;
page.getTextContent().then( function(textContent){
//console.log(textContent.items[0]);0
if( null != textContent.items ){
var page_text = "";
var last_block = null;
for( var k = 0; k < textContent.items.length; k++ ){
var block = textContent.items[k];
if( last_block != null && last_block.str[last_block.str.length-1] != ' '){
if( block.x < last_block.x )
page_text += "\r\n";
else if ( last_block.y != block.y && ( last_block.str.match(/^(\s?[a-zA-Z])$|^(.+\s[a-zA-Z])$/) == null ))
page_text += ' ';
}
page_text += block.str;
last_block = block;
}
textContent != null && console.log("page " + n + " finished."); //" content: \n" + page_text);
layers[n] = page_text + "\n\n";
}
++ self.complete;
//callbackPageDone( self.complete, total );
if (self.complete == total){
window.setTimeout(function(){
var full_text = "";
var num_pages = Object.keys(layers).length;
for( var j = 1; j <= num_pages; j++)
full_text += layers[j] ;
console.log(full_text);
}, 1000);
}
}); // end of page.getTextContent().then
}); // end of page.then
} // of for
});
}; // end of pdfToText()
}; // end of class
var pdff = new Pdf2TextClass();
pdff.pdfToText('PDF_URL');
</script>