【问题标题】:iText7 : com.itextpdf.kernel.PdfException: Document was closed. It is impossible to execute actioniText7:com.itextpdf.kernel.PdfException:文档已关闭。无法执行动作
【发布时间】:2018-02-20 10:30:46
【问题描述】:

我在 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 行)。

【问题讨论】:

    标签: java pdf itext itext7


    【解决方案1】:

    我已经复制了你的代码:

    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之类的参数是关于什么的。您能否执行我的示例,并告诉我问题是否仍然存在?

    • 如果我的示例仍然抛出错误:可能您使用的不是最新版本的 iText 7。请升级并重新尝试。
    • 如果我的示例没有引发错误:尝试逐步调整我的示例,直到错误再次发生。告诉我们您在错误发生前执行的最后一步。

    更新:

    当您创建PdfFont 并在PdfDocument 的上下文中使用该PdfFont 实例时,该PdfFont“属于”该文档,您不能再重复使用它。您应该为每个文档创建一个新的 PdfFont 实例。这并不意味着您不能重复使用 FontProgram

    我将更新我的示例。我使用FontProgramFactory 创建一个FontProgram(我使用了快速而肮脏的方式)。我不重用任何PdfFont,但我使用FontProgram 为每个PdfDocument 创建一个新的PdfFont

    【讨论】:

    • 感谢您的回复。我发现使用字体“MS Gothic”(日文 Windows 上的标准字体)设置表单值会导致此错误。看起来有些字体会导致此错误,而其他字体则不会。我也尝试过使用 HELVETICA,它不会导致错误。我已经更新了我的程序。
    • 我会更新我的答案。简短的回答:不允许重用 PdfFont 对象。您应该改用FontProgram
    • 我已经更新了答案中的示例。使用 msgothic.ttc 时,我能够重现错误,然后我通过重用 FontProgram 而不是 PdfFont 来修复错误。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-12
    • 1970-01-01
    • 1970-01-01
    • 2022-11-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多