Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iText7 : com.itextpdf.kernel.PdfException: Document was closed. It is impossible to execute action

I got com.itextpdf.kernel.PdfException: Document was closed. It is impossible to execute action. error on iText7.

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  }               

I got this output.

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) )

Why I got this error? How can I fix?

[UPDATE] I found setting value with font "MS Gothic" (Standard font on Japanese Windows) cause this error. It seems some fonts cause this error while others not. I also tried with HELVETICA, but it does not cause error. I have updated my program (from line 1 to 14, and line 38 to 41).

like image 527
N.F. Avatar asked May 05 '26 16:05

N.F.


1 Answers

I have made an almost literal copy of your code:

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());
                }
            }
        }
    }
}

It doesn't throw any errors when I run it.

I had to make some changes, because I didn't know what parameters such as keyList were about. Can you execute my example, and tell me if the problem persists?

  • If my example still throws an error: maybe you aren't using the most recent version of iText 7. Please upgrade and try anew.
  • If my example doesn't throw an error: try adapting my example step by step until the error happens again. Tell us which was the last step you performed before the error occurred.

Update:

When you create a PdfFont and when you use that PdfFont instance in the context of a PdfDocument, that PdfFont "belongs" to that document, and you can no longer reuse it. You should create a new PdfFont instance for every document. This doesn't mean you can't reuse a FontProgram though.

I'll have updated my example. I use the FontProgramFactory to create a FontProgram (I used the quick & dirty way). I don't reuse any PdfFont, but I use the FontProgram to create a new PdfFont for every PdfDocument.

like image 100
Bruno Lowagie Avatar answered May 07 '26 05:05

Bruno Lowagie



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!