我有以下合并我的 PDF 檔案的方法。但是,在檔案有水印的某些情況下,該方法會引發錯誤。
public void doMergeUsingItext7(List<InputStream> list, OutputStream outputStream) throws SSException {
try (com.itextpdf.kernel.pdf.PdfWriter writer = new com.itextpdf.kernel.pdf.PdfWriter(outputStream);) {
writer.setSmartMode(Boolean.TRUE);
try (com.itextpdf.kernel.pdf.PdfDocument pdfDoc = new com.itextpdf.kernel.pdf.PdfDocument(writer)) {
pdfDoc.initializeOutlines();
list.forEach((in) -> {
try (com.itextpdf.kernel.pdf.PdfReader reader = new com.itextpdf.kernel.pdf.PdfReader(in);) {
reader.setUnethicalReading(Boolean.TRUE);
try (com.itextpdf.kernel.pdf.PdfDocument addedDoc = new com.itextpdf.kernel.pdf.PdfDocument(reader)) { //ERROR IS THROWN ON THIS LINE
addedDoc.copyPagesTo(1, addedDoc.getNumberOfPages(), pdfDoc);
logger.log(Level.INFO, "Successfully Added the Document to PDF");
} catch (Exception e) {
ExceptionUtils.printRootCauseStackTrace(e);
}
} catch (IOException ex) {
ExceptionUtils.printRootCauseStackTrace(ex);
} catch (Exception e) {
ExceptionUtils.printRootCauseStackTrace(e);
}
});
}
} catch (Exception ex) {
throw new SSException(ex, "Print Version Failed");
}
}
當檔案有水印時拋出以下錯誤...
com.itextpdf.kernel.PdfException: Illegal length value.
at com.itextpdf.kernel.pdf.PdfEncryption.readAndSetCryptoModeForStdHandler(PdfEncryption.java:523)
at com.itextpdf.kernel.pdf.PdfEncryption.<init>(PdfEncryption.java:229)
at com.itextpdf.kernel.pdf.PdfReader.readDecryptObj(PdfReader.java:1251)
at com.itextpdf.kernel.pdf.PdfReader.readPdf(PdfReader.java:685)
at com.itextpdf.kernel.pdf.PdfDocument.open(PdfDocument.java:1871)
at com.itextpdf.kernel.pdf.PdfDocument.<init>(PdfDocument.java:252)
at com.itextpdf.kernel.pdf.PdfDocument.<init>(PdfDocument.java:234)
at gov.ca.lc.util.PdfUtilFuntions.lambda$doMergeUsingItext7$0(PdfUtilFuntions.java:180)
at java.util.ArrayList.forEach(ArrayList.java:1257)
at gov.ca.lc.util.PdfUtilFuntions.doMergeUsingItext7(PdfUtilFuntions.java:176)
我不確定檔案中的哪些內容無法合并。非常感謝有關解決此問題的任何幫助。謝謝。
uj5u.com熱心網友回復:
這是 iText 中的一個錯誤。
有問題的 PDF 已加密。它的加密字典的V值為 1(“加密密鑰長度為 40 位的 RC4 或 AES 演算法”)和3的R值(“對于使用 V 值為 2 或 3 加密的檔案,或任何“安全性”版本 3 或更高版本的處理程式”訪問權限設定為 0”)。
甲長度僅指定用于密鑰長度值V 2或3,為V 1的密鑰長度被固定為40。盡管如此,在iText的的情況下,[R 3需要一個長度值。
由于檔案的加密字典中沒有Length值,iText 無法讀取該檔案。
附帶說明:如今 40 位密鑰長度的安全性是沒有安全性的。因此,該問題很可能沒有更早出現,因為使用V 1 安全性(或一般的 40 位密鑰長度安全性)是無用的,因此沒有認真對待用例。
快速修復
如果您不回避重新編譯 iText,則修復錯誤很容易。只需編輯 iText 內核類com.itextpdf.kernel.pdf.PdfEncryption。它的方法readAndSetCryptoModeForStdHandler以
int cryptoMode;
int length = 0;
PdfNumber rValue = encDict.getAsNumber(PdfName.R);
if (rValue == null)
throw new PdfException(KernelExceptionMessageConstant.ILLEGAL_R_VALUE);
int revision = rValue.intValue();
boolean embeddedFilesOnlyMode = readEmbeddedFilesOnlyFromEncryptDictionary(encDict);
switch (revision) {
case 2:
cryptoMode = EncryptionConstants.STANDARD_ENCRYPTION_40;
break;
case 3:
PdfNumber lengthValue = encDict.getAsNumber(PdfName.Length);
if (lengthValue == null)
throw new PdfException(KernelExceptionMessageConstant.ILLEGAL_LENGTH_VALUE);
length = lengthValue.intValue();
if (length > 128 || length < 40 || length % 8 != 0)
throw new PdfException(KernelExceptionMessageConstant.ILLEGAL_LENGTH_VALUE);
cryptoMode = EncryptionConstants.STANDARD_ENCRYPTION_128;
break;
這里簡單替換
if (lengthValue == null)
throw new PdfException(KernelExceptionMessageConstant.ILLEGAL_LENGTH_VALUE);
length = lengthValue.intValue();
經過
length = 40;
if (lengthValue != null)
length = lengthValue.intValue();
(我使用了具有相同行數的替代品,以便更輕松地解釋后面的堆疊跟蹤。)
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/379609.html
上一篇:從CSV檔案中提取特定字串和整數并使用python將其寫入.txt檔案
下一篇:切割Apache虛擬主機塊
