COSStream has been closed and cannot be read. Perhaps its enclosing PDDocument has been closed?

JoffJoff :

Essentially, I am attempting to create a small tool in Java where I take the text from some kind of user input, think of an ordinary text box, and create a PDF file with it.

So far, I managed to scrape something really quickly with my barebones knowledge of PDFBox.

In my application, I am instantiating this class(the one shown below) in another one with GUI elements and if I input text, in let's say a text box, and running this PDFLetter script once - it works like a charm but running it a second time, it crashes and gives me this annoying error:

COSStream has been closed and cannot be read. Perhaps it's enclosing PDDocument has been closed?

I do not really see any way that I could trigger this error in my code. I thought it had something to do with my rudimentary 'jump to next page' solution but it works in its current state, so I do not know what to believe anymore.

The way I am instantiating the class, in case you need to know, is like this:

PDFLetter.PDFLetterGenerate(textInput.getValue().toString());   

Additionally, I thought it had to be some kind of a problem with garbage collection that triggered the problem but I no longer think that this is the case.

public class PDFLetter {
    private static final int PAGE_MARGIN = 80;

    static float TABLE_HEIGHT;  

    static Boolean newPage = false;

public static String text = // null;
        "Ding Dong ding dong Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et "
        + "Imperdiet dui accumsan sit amet. Risus in hendrerit gravida rutrum quisque non tellus orci ac.";

static List<String> textList = new ArrayList<String>();

PDDocument document = new PDDocument();
static PDPage main_page = new PDPage();
static PDPage new_page = new PDPage(); 

static File file = new File("C:/PDFTests/temp.pdf"); 

public void PDFLetterGenerate (String args) throws Exception {
    text = args;
    text = text.replace("\n", "").replace("\r", "");

    if(file.exists()) file.delete();
    file.createNewFile();
    //Creating PDF document object 
    PDDocument document = new PDDocument();       
    document.addPage(main_page);  
    mainBody(document, main_page);      
    document.addPage(new_page);                          
    if(!newPage) document.removePage(new_page);

    document.save(file);
    document.close(); 
}

public static void mainBody(PDDocument doc, PDPage page) throws Exception { 
        final float width = page.getMediaBox().getWidth()-(2*PAGE_MARGIN);
        int fontSize = 11;
        float leading = 1.5f * fontSize;
        final float max = 256;
        PDFont pdfFont = PDType1Font.HELVETICA;

        @SuppressWarnings("deprecation")
        PDPageContentStream contentStream = new PDPageContentStream(doc, page, true, true);

        int lastSpace = -1;
        while (text.length() > 0){
            int spaceIndex = text.indexOf(' ', lastSpace + 1);
            if (spaceIndex < 0) spaceIndex = text.length();
            String subString = text.substring(0, spaceIndex);
            float size = fontSize * pdfFont.getStringWidth(subString) / 1000;

            if (size > width){
                if (lastSpace < 0) lastSpace = spaceIndex;
                subString = text.substring(0, lastSpace);
                textList.add(subString);
                text = text.substring(lastSpace).trim();
                lastSpace = -1;
            }

            else if (spaceIndex == text.length()){
                textList.add(text);
                text = "";
            }

            else{
                lastSpace = spaceIndex;
            }
        }

        contentStream.beginText();
        contentStream.setFont(pdfFont, fontSize);
        contentStream.newLineAtOffset(PAGE_MARGIN, TABLE_HEIGHT);


        @SuppressWarnings("deprecation")
        PDPageContentStream newStream = new PDPageContentStream(doc, new_page, true, true);

        int nextPage_i = 0;

        for (int i=0; i<textList.size(); i++)//String line: textList){
            System.out.println("HEIGHT: "+ TABLE_HEIGHT);
            nextPage_i = i;
            String line = textList.get(i);
            float charSpacing = 0;

            if (line.length() > 1){         
                float size = fontSize * pdfFont.getStringWidth(line) / 1000;
                float free = width - size;
                if (free > 0){
                    charSpacing = free / (line.length() - 1);
                }
                TABLE_HEIGHT = TABLE_HEIGHT - 10;
            }

            contentStream.setCharacterSpacing(charSpacing); 
            contentStream.showText(line);
            contentStream.newLineAtOffset(0, -leading);

            if(TABLE_HEIGHT <= 280){  
                contentStream.endText();  
                contentStream.close(); 
                newPage = true;
                break; 
            } 
        } 

        if(!newPage){
            contentStream.endText();  
            contentStream.close(); 
        }

        else if (newPage){          
            float NEW_HEIGHT = 600;             
            newStream.beginText();
            newStream.setFont(pdfFont, fontSize);
            newStream.newLineAtOffset(PAGE_MARGIN, NEW_HEIGHT);

            for (int j=nextPage_i; j<textList.size(); j++)//String line: textList){
                System.out.println("HEIGHT: "+ NEW_HEIGHT);
                nextPage_i = j;
                String line = textList.get(j);
                float charSpacing = 0;

                if (line.length() > 1){         
                    float size = fontSize * pdfFont.getStringWidth(line) / 1000;
                    float free = width - size;
                    if (free > 0)
                    {
                        charSpacing = free / (line.length() - 1);
                    }
                    NEW_HEIGHT = NEW_HEIGHT - 10; 
                }
                newStream.setCharacterSpacing(charSpacing); 
                newStream.showText(line);
                newStream.newLineAtOffset(0, -leading);
            }
            newStream.endText();  
            newStream.close();
        }
        lastSpace = -1;
    }
mkl :

Pull the PDPage instantiations into PDFLetterGenerate:

public void PDFLetterGenerate (String args) throws Exception {
    PDPage main_page = new PDPage();
    PDPage new_page = new PDPage(); 

    text = args;
    text = text.replace("\n", "").replace("\r", "");

    if(file.exists()) file.delete();
    file.createNewFile();
    //Creating PDF document object 
    PDDocument document = new PDDocument();       
    document.addPage(main_page);  
    mainBody(document, main_page);      
    document.addPage(new_page);                          
    if(!newPage) document.removePage(new_page);

    document.save(file);
    document.close(); 
}

In your code the pages are instantiated once and the underlying streams are closed after the first run of PDFLetterGenerate when the local PDDocument document is closed after having the pages added to it.

Furthermore, also make new_page an argument of mainBody instead of counting on a static variable to hold it.

There are a number of other issues in your code, but the changes above should get you started.

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=421131&siteId=1