如何使用 NodeJS 替换 PDF 文件中的字符串?

Posted

技术标签:

【中文标题】如何使用 NodeJS 替换 PDF 文件中的字符串?【英文标题】:How do I replace a string in a PDF file using NodeJS? 【发布时间】:2016-08-15 04:30:57 【问题描述】:

我有一个模板 PDF 文件,我想替换一些标记字符串以生成新的 PDF 文件并保存它们。最好/最简单的方法是什么?我不需要添加图形或任何花哨的东西,只是一个简单的文本替换,所以我不想要太复杂的东西。

谢谢!

编辑:刚刚找到HummusJS,我看看能不能进步,发在这里。

【问题讨论】:

你好,曼努埃尔!你找到解决办法了吗? 我也很好奇.. 我也有同样的情况,你找到解决办法了吗? 【参考方案1】:

我通过搜索找到了这个问题,所以我认为它应该得到答案。我在这里找到了 BrighTide 的答案:https://github.com/galkahana/HummusJS/issues/71#issuecomment-275956347

基本上,有一个非常强大的 Hummus 包,它使用用 C++ 编写的库(当然是跨平台的)。我认为该 github 评论中给出的答案可以这样功能化:

var hummus = require('hummus');

/**
 * Returns a byteArray string
 * 
 * @param string str - input string
 */
function strToByteArray(str) 
  var myBuffer = [];
  var buffer = new Buffer(str);
  for (var i = 0; i < buffer.length; i++) 
      myBuffer.push(buffer[i]);
  
  return myBuffer;


function replaceText(sourceFile, targetFile, pageNumber, findText, replaceText)   
    var writer = hummus.createWriterToModify(sourceFile, 
        modifiedFilePath: targetFile
    );
    var sourceParser = writer.createPDFCopyingContextForModifiedFile().getSourceDocumentParser();
    var pageObject = sourceParser.parsePage(pageNumber);
    var textObjectId = pageObject.getDictionary().toJSObject().Contents.getObjectID();
    var textStream = sourceParser.queryDictionaryObject(pageObject.getDictionary(), 'Contents');
    //read the original block of text data
    var data = [];
    var readStream = sourceParser.startReadingFromStream(textStream);
    while(readStream.notEnded())
        Array.prototype.push.apply(data, readStream.read(10000));
    
    var string = new Buffer(data).toString().replace(findText, replaceText);

    //Create and write our new text object
    var objectsContext = writer.getObjectsContext();
    objectsContext.startModifiedIndirectObject(textObjectId);

    var stream = objectsContext.startUnfilteredPDFStream();
    stream.getWriteStream().write(strToByteArray(string));
    objectsContext.endPDFStream(stream);

    objectsContext.endIndirectObject();

    writer.end();


// replaceText('source.pdf', 'output.pdf', 0, /REPLACEME/g, 'My New Custom Text');

更新: 编写示例时使用的版本是1.0.83,最近可能会发生变化。

更新 2: 最近我遇到了另一个字体不同的 PDF 文件的问题。由于某种原因,文本被分成小块,即字符串QWERTYUIOPASDFGHJKLZXCVBNM1234567890- 被表示为-286(Q)9(WER)24(T)-8(YUIOP)116(ASDF)19(GHJKLZX)15(CVBNM1234567890-) 我不知道除了编写一个正则表达式之外还能做什么。所以,而不是这一行:

var string = new Buffer(data).toString().replace(findText, replaceText);

我现在有这样的东西:

var string = Buffer.from(data).toString();

var characters = REPLACE_ME;
var match = [];
for (var a = 0; a < characters.length; a++) 
    match.push('(-?[0-9]+)?(\\()?' + characters[a] + '(\\))?');


string = string.replace(new RegExp(match.join('')), function(m, m1) 
    // m1 holds the first item which is a space
    return m1 + '( ' + REPLACE_WITH_THIS + ')';
);

【讨论】:

我收到以下错误:TypeError: pageObject.getDictionary(...).toJSObject(...).Contents.getObjectID is not a function @Nithin 使用的版本是 1.0.83,也许有些改变...但是您是否先尝试使用最简单的 pdf 文件?打开pdf时可以选择文本吗? @Nithin 表示文本已矢量化,您无法替换它,因为它是以矢量形式呈现的 @Nithin 我会检查pageObject.getDictionary().toJSObject() 返回的内容,而不是试图猜测 @Nithin 你在哪里找到这个?【参考方案2】:

还有另一个 Node.js 包 asposepdfcloud,Aspose.PDF Cloud SDK for Node.js。您可以使用它方便地替换 PDF 文档中的文本。它的免费计划每月提供 150 个积分。这是替换PDF文档中文本的示例代码,不要忘记先安装asposepdfcloud。

const  PdfApi  = require("asposepdfcloud");
const  TextReplaceListRequest = require("asposepdfcloud/src/models/textReplaceListRequest");
const  TextReplace = require("asposepdfcloud/src/models/textReplace");

// Get App key and App SID from https://aspose.cloud 
pdfApi = new PdfApi("xxxxx-xxxxx-xxxx-xxxxxxxxxxx", "xxxxxxxxxxxxxxxxxxxxxb");

var fs = require('fs');

const name = "02_pages.pdf";
const remoteTempFolder = "Temp";
//const localTestDataFolder = "C:\\Temp";
//const path = remoteTempFolder + "\\" + name;
//var data = fs.readFileSync(localTestDataFolder + "\\" + name);
    
const textReplace= new TextReplace();
        textReplace.oldValue= "origami"; 
        textReplace.newValue= "aspose";
        textReplace.regex= false;

const textReplace1= new TextReplace();
        textReplace1.oldValue= "candy"; 
        textReplace1.newValue= "biscuit";
        textReplace1.regex= false;
    
const trr = new TextReplaceListRequest();
            trr.textReplaces = [textReplace,textReplace1];

// Upload File
//pdfApi.uploadFile(path, data).then((result) =>   
//                     console.log("Uploaded File");    
//                    ).catch(function(err) 
    // Deal with an error
//    console.log(err);
//);


// Replace text
pdfApi.postDocumentTextReplace(name, trr, null, remoteTempFolder).then((result) =>     
    console.log(result.body.code);                  
).catch(function(err) 
    // Deal with an error
    console.log(err);
);

P.S:我是 aspose 的开发布道者。

【讨论】:

以上是关于如何使用 NodeJS 替换 PDF 文件中的字符串?的主要内容,如果未能解决你的问题,请参考以下文章

用nodejs替换文件中的字符串

如何使用 PHP 替换 PDF 文件中的内容?

如何替换或修改嵌入在 PDF 文件中的字体或字形?

Python:如何替换pdf中的文本

如何全局替换PDF中的字体

使用Itext搜索和替换PDF