我在iText7上收到com.itextpdf.kernel.PdfException: Document was closed. It is impossible to execute action.
错误。
1 // UPDATE FROM HERE
2 PdfFont font;
3 {
4 GcsFilename gcsFilename = new GcsFilename("fonts", "msgothic001.ttf");
5 try (GcsInputChannel inputChannel =
6 gcsService.openPrefetchingReadChannel(gcsFilename, 0, BUFFER_SIZE)) {
7 font =
8 PdfFontFactory.createFont(
9 getBytes(Channels.newInputStream(inputChannel)),
10 PdfEncodings.IDENTITY_H,
11 true);
12 }
13 }
14 // UPDATE UNTIL HERE
15
16 WriterProperties wp = new WriterProperties();
17 wp.useSmartMode();
18 try (PdfDocument writeDoc = new PdfDocument(new PdfWriter(outputStream, wp))) {
19
20 List<Integer> keyList = Arrays.asList(Integer.valueOf(1), Integer.valueOf(2), Integer.valueOf(3));
21 for (Integer keyNumber : keyList) {
22 LOGGER.info(keyNumber); // (1)
23 ByteArrayOutputStream baos = new ByteArrayOutputStream();
24 try (PdfWriter writer = new PdfWriter(baos);
25 PdfDocument readDoc =
26 new PdfDocument(new PdfReader(new ByteArrayInputStream(inputBytes)), writer)) {
27 PdfAcroForm pdfAcroForm = PdfAcroForm.getAcroForm(readDoc, false);
28 Map<String, PdfFormField> fieldMap = pdfAcroForm.getFormFields();
29 if (fieldMap != null && fieldMap.size() > 0) {
30 Set<String> fieldNameSet = new HashSet<>(fieldMap.keySet());
31 for (String fieldName : fieldNameSet) {
32 pdfAcroForm.renameField(fieldName, fieldName + "_" + keyNumber);
33 }
34 fieldMap = pdfAcroForm.getFormFields();
35 }
36
37
38 // UPDATE FROM HERE
39 PdfFormField form = fieldMap.get("Customer_" + keyNumber);
40 form.setFont(font).setValue("Test Test");
41 // UPDATE UNTIL HERE
42
43 } // (2) We got the error on this line
44
45 try (PdfDocument readDoc =
46 new PdfDocument(new PdfReader(new ByteArrayInputStream(baos.toByteArray())))) {
47 readDoc.copyPagesTo(1, readDoc.getNumberOfPages(), writeDoc, new PdfPageFormCopier());
48 }
49 }
50 }
我得到了这个输出。
13:55:45.962 1 // (1)
13:55:47.252 2 // (1)
13:55:47.782 com.itextpdf.kernel.PdfException: Document was closed. It is impossible to execute action.
at com.itextpdf.kernel.pdf.PdfDocument.checkClosingStatus(PdfDocument.java:1887)
at com.itextpdf.kernel.pdf.PdfDocument.getWriter(PdfDocument.java:645)
at com.itextpdf.kernel.pdf.PdfObject.makeIndirect(PdfObject.java:228)
at com.itextpdf.kernel.pdf.PdfDictionary.makeIndirect(PdfDictionary.java:491)
at com.itextpdf.kernel.pdf.PdfDictionary.makeIndirect(PdfDictionary.java:57)
at com.itextpdf.kernel.pdf.PdfObject.makeIndirect(PdfObject.java:249)
at com.itextpdf.kernel.pdf.PdfDictionary.makeIndirect(PdfDictionary.java:479)
at com.itextpdf.kernel.pdf.PdfDictionary.makeIndirect(PdfDictionary.java:57)
at com.itextpdf.kernel.font.PdfFont.makeObjectIndirect(PdfFont.java:600)
at com.itextpdf.kernel.font.PdfType0Font.getFontDescriptor(PdfType0Font.java:672)
at com.itextpdf.kernel.font.PdfType0Font.flushFontData(PdfType0Font.java:828)
at com.itextpdf.kernel.font.PdfType0Font.flush(PdfType0Font.java:600)
at com.itextpdf.kernel.pdf.PdfDocument.flushFonts(PdfDocument.java:1848)
at com.itextpdf.kernel.pdf.PdfDocument.close(PdfDocument.java:800)
at (our source (2) )
为什么会出现此错误?我该如何解决?
[更新]
我发现字体“MS Gothic”(日语Windows上的标准字体)的设置值导致此错误。似乎有些字体导致此错误,而另一些则不是。我也尝试过HELVETICA,但它不会导致错误。我已经更新了程序(从1行到14行,以及38行到41行)。
最佳答案
我已经为您的代码制作了几乎文字的副本:
package com.itextpdf.samples;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import com.itextpdf.forms.PdfAcroForm;
import com.itextpdf.forms.PdfPageFormCopier;
import com.itextpdf.forms.fields.PdfFormField;
import com.itextpdf.io.font.FontProgram;
import com.itextpdf.io.font.FontProgramFactory;
import com.itextpdf.kernel.font.PdfFontFactory;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfReader;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.kernel.pdf.WriterProperties;
public class Test {
public static void main(String[] args) throws IOException {
FontProgram fontProgram = FontProgramFactory.createFont("c:/windows/fonts/msgothic.ttc,1");
FileOutputStream outputStream = new FileOutputStream("test.pdf");
WriterProperties wp = new WriterProperties();
wp.useSmartMode();
try (PdfDocument writeDoc = new PdfDocument(new PdfWriter(outputStream, wp))) {
for (int keyNumber = 0; keyNumber < 3; keyNumber++) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try (PdfWriter writer = new PdfWriter(baos);
PdfDocument readDoc =
new PdfDocument(new PdfReader("form.pdf"), writer)) {
PdfAcroForm pdfAcroForm = PdfAcroForm.getAcroForm(readDoc, false);
Map<String, PdfFormField> fieldMap = pdfAcroForm.getFormFields();
if (fieldMap != null && fieldMap.size() > 0) {
Set<String> fieldNameSet = new HashSet<>(fieldMap.keySet());
for (String fieldName : fieldNameSet) {
pdfAcroForm.renameField(fieldName, fieldName + "_" + keyNumber);
}
fieldMap = pdfAcroForm.getFormFields();
}
PdfFormField form = fieldMap.get("name_" + keyNumber);
form.setFont(PdfFontFactory.createFont(fontProgram)).setValue("Test Test");
}
try (PdfDocument readDoc =
new PdfDocument(new PdfReader(new ByteArrayInputStream(baos.toByteArray())))) {
readDoc.copyPagesTo(1, readDoc.getNumberOfPages(), writeDoc, new PdfPageFormCopier());
}
}
}
}
}
运行它时不会抛出任何错误。
我必须进行一些更改,因为我不知道
keyList
等参数是关于什么的。您能否执行我的示例,并告诉我问题是否仍然存在?更新:
当您创建
PdfFont
并在PdfFont
的上下文中使用该PdfDocument
实例时,该PdfFont
“属于”该文档,您将无法再使用它。您应该为每个文档创建一个新的PdfFont
实例。这并不意味着您不能重用FontProgram
。我将更新我的示例。我使用
FontProgramFactory
创建一个FontProgram
(我使用了快速又脏的方法)。我不重用任何PdfFont
,但是我使用FontProgram
为每个PdfFont
创建一个新的PdfDocument
。