Lost a week for finding solution, but still fail. Maybe know somebody: I try to replace token, eg @test to numbers 123456 in .pdf file using pdfbox.
It replace it, but in output instead of numbers I have squares or question mark inside square or numbers shown over each other. Only what I realize is that it depends on selected font. And I can’t figure out where is the mistake.
Note: we suppose that it’s a port issue and test on Java build in a v 2.0 and face with the same issue.
Maybe somebody face with similar problem and know solution?
Tech details:
- Version: PDFBox.NET-1.8.9, which taken from http://www.squarepdf.net/pdfbox-in-net
- Language: C#
- .NET Frameworks 4.5.2
- Used fonts: times new roman, tahoma, courier, calibri.
MS Word creation:
- Just right click in desktop
- Select Microsoft Word Document from create new point
- Print inside text: @test
Script:
private void ReplaceTextInPdf(string inputPath, string outputPath) {
PDDocument doc = null;
try {
File input = new File(inputPath);
doc = PDDocument.loadNonSeq(input, null);
List pages = doc.getDocumentCatalog().getAllPages();
for (int i = 0; i < pages.size(); i++) {
PDPage page = (PDPage)pages.get(i);
PDStream contents = page.getContents();
PDFStreamParser parser = new PDFStreamParser(contents.getStream());
parser.parse();
List tokens = parser.getTokens();
for (int j = 0; j < tokens.size(); j++) {
Object next = tokens.get(j);
if (next is PDFOperator) {
PDFOperator op = (PDFOperator)next;
//Tj and TJ are the two operators that display
//strings in a PDF
if (op.getOperation() == "Tj") {
//Tj takes one operator and that is the string
//to display so lets update that operator
COSString previous = (COSString)tokens.get(j - 1);
String tempString = previous.getString();
tempString = tempString.replace("@test", "123456");
previous.reset();
previous.append(tempString.getBytes());
} else if (op.getOperation() == "TJ") {
String tempString = "";
COSString cosString = null;
COSArray previous = (COSArray)tokens.get(j - 1);
for (int k = 0; k < previous.size(); k++) {
Object arrElement = previous.getObject(k);
if (arrElement is COSString) {
cosString = (COSString)arrElement;
tempString += cosString.getString();
cosString.reset();
}
}
if (tempString != null && tempString.trim().length() > 0) {
tempString = tempString.replace("@test", "123456");
for (int k = 0; k < previous.size(); k++) {
Object arrElement = previous.getObject(k);
if (arrElement is COSString) {
cosString.reset();
cosString.append(tempString.getBytes("ISO-8859-1"));
break;
}
}
}
}
}
}
//now that the tokens are updated we will replace the
//page content stream.
PDStream updatedStream = new PDStream(doc);
OutputStream out1 = updatedStream.createOutputStream();
ContentStreamWriter tokenWriter = new ContentStreamWriter(out1);
tokenWriter.writeTokens(tokens);
page.setContents(updatedStream);
}
doc.save(outputPath);
} finally {
if (doc != null) {
doc.close();
}
}
}