Search code examples
itextopenpdf

OpenPDF columnText.go creating corrupt document


I keep getting an error of

Error

when I try writing to the PDF with columnText. setSimpleColumn() used to work fine, but now this code is throwing the error, also when I tried using a setColumns() it also is throwing an error. I can't think of what is causing the error. Was I supposed to close the columnText somehow?

The immediately related code is:

fun testBox(content: List, font: List, page: Int, leftLimit: Float, rightLimit: Float, topLimit: Float, bottomLimit: Float){
val columnText = ColumnText(setCanvas("$filepath$name.pdf",page))
columnText.alignment = ALIGN_JUSTIFIED
columnText.runDirection = RUN_DIRECTION_RTL
columnText.setSimpleColumn(leftLimit, bottomLimit, rightLimit, getRectangle("LETTER").top-topLimit)
var i = 0

while (i < content.size) {
    columnText.addText(Chunk(content[i], font[i]))
    columnText.go()
    i++
}
}

I'll show more code if needed, but I don't think the rest of it is related to the issue.

I'm really stumped, and I can't find much info on this issue.

This is the resulting file: https://drive.google.com/file/d/135EhLyiyDj6iAexUJ0upRdG6eXHYXVdw/view?usp=sharing

EDIT: I forgot that I made the function setCanvas in order to save a bunch of code, here is the function:

fun setCanvas(file: String, page: Int): PdfContentByte? {
    val reader = PdfReader(file)
    val stamper = PdfStamper(reader, FileOutputStream(File(file)))
    if(reader.numberOfPages < page){ stamper.insertPage(reader.numberOfPages + (page-reader.numberOfPages), reader.getPageSize(1) ?: getRectangle("LETTER")); if (page - reader.numberOfPages != 1){throw Error("EMPTY PAGE!")}}
    return stamper.getOverContent(page)
}

EDIT 2: [combined two functions]

    testBox(listOf(content1,content2,content3), listOf(font,fontBold,font), 1, document.left(), document.right(), document.bottom(),document.top())


fun testBox(content: List<String>, font: List<Font>, page: Int, leftLimit: Float, rightLimit: Float, topLimit: Float, bottomLimit: Float){
    val reader = PdfReader("$filepath$name.pdf")
    val stamper = PdfStamper(reader, FileOutputStream(File("$filepath$name - edit.pdf")))
    if(reader.numberOfPages < page){ stamper.insertPage(reader.numberOfPages + (page-reader.numberOfPages), reader.getPageSize(1) ?: getRectangle("LETTER")); if (page - reader.numberOfPages > 0){throw Error("EMPTY PAGE!")}}
    val columnText = ColumnText(stamper.getOverContent(page))

    columnText.alignment = ALIGN_JUSTIFIED
    columnText.runDirection = RUN_DIRECTION_RTL
    columnText.setSimpleColumn(leftLimit, bottomLimit, getRectangle("LETTER").right - rightLimit, getRectangle("LETTER").top- topLimit)
    var i = 0
    while (i<content.size) {
        columnText.addText(Chunk(content[i], font[i]))
        columnText.go()
        i++
    }
}

link: https://drive.google.com/file/d/1ybvDVSxKOJdbnA2fSRjEmxlDszIktWTL/view?usp=sharing


Solution

  • There are two errors in your original code:

    • You use the same source and target file for stamping.
    • You don't keep a reference to the PdfStamper to close it after manipulating the PDF.

    The first problem causes the file to be truncated before it is completely read. This you fixed in your edit.

    The second may cause your output PDF to not become finished, missing a necessary trailer.

    After also fixing the second problem your code finally stopped producing a corrupt file.