Мне нужно заменить строку / строку в PDF согласно координатным заполнителям и заново выровнять содержимое PDF.
Я могу найти текст в соответствии с координатой, а также успешно заменить. Но предположим, что если новый текст / строка длиннее существующей строки, то pdf не выравнивает существующий текст и строку, как документ MS Word.
========================================================================
public static void main(String[] args) throws IOException {
String inFile = "format1.pdf";
String outFile = "formatCov.pdf";
String oldValue = "DRAFT";
String newValue = "Final test";
PDDocument document = null;
try {
document = PDDocument.load(new File(inFile));
if (document.isEncrypted()) {
System.err.println("Error: Encrypted documents are not supported for this example.");
System.exit(1);
}
System.out.println(oldValue + " => " + newValue);
document = _ReplaceText(document, oldValue, newValue);
document.save(outFile);
} finally {
if (document != null) {
document.close();
}
}
}
private static PDDocument _ReplaceText(PDDocument document, String searchString, String replacement)
throws IOException {
if (StringUtils.isEmpty(searchString) || StringUtils.isEmpty(replacement)) {
return document;
}
for (PDPage page : document.getPages()) {
PDFStreamParser parser = new PDFStreamParser(page);
parser.parse();
List tokens = parser.getTokens();
for (int j = 0; j < tokens.size(); j++) {
Object next = tokens.get(j);
//System.out.println("next =" + next.toString());
if (next instanceof Operator) {
Operator op = (Operator) next;
System.out.println("operator = " + op.getName());
String pstring = "";
int prej = 0;
// Tj and TJ are the two operators that display strings in a PDF
if (op.getName().equals("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 string = previous.getString();
System.out.println(string);
string = string.replaceFirst(searchString, replacement);
previous.setValue(string.getBytes());
} else if (op.getName().equals("TJ")) {
COSArray previous = (COSArray) tokens.get(j - 1);
for (int k = 0; k < previous.size(); k++) {
Object arrElement = previous.getObject(k);
if (arrElement instanceof COSString) {
COSString cosString = (COSString) arrElement;
String string = cosString.getString();
if (j == prej) {
pstring += string;
} else {
prej = j;
pstring = string;
}
}
}
System.out.println(pstring);
//if (searchString.contains(pstring.trim())) {
if (pstring.trim().contains(searchString)) {
System.out.println(pstring.trim());
COSString cosString2 = (COSString) previous.getObject(0);
cosString2.setValue(replacement.getBytes());
int total = previous.size() - 1;
for (int k = total; k > 0; k--) {
previous.remove(k);
}
}
}
}
}
// now that the tokens are updated we will replace the page content stream.
PDStream updatedStream = new PDStream(document);
OutputStream out = updatedStream.createOutputStream(COSName.FLATE_DECODE);
ContentStreamWriter tokenWriter = new ContentStreamWriter(out);
tokenWriter.writeTokens(tokens);
out.close();
page.setContents(updatedStream);
}
return document;
}