Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to convert iTextPDF Document to Byte Array

I need to convert iTextPDF Document file to byte[] after it's created in memory. I have already tested that I've no problem with creating PDF properly. The problem is how to convert it to byte array to store in DB.

Here's my code:

Document generatedDocument = reportService.generateRequestForm(scdUser, jsonObject, 0, null);
reportService.generateRequestForm(scdUser, jsonObject, 0, null);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PdfWriter pdfWriter = PdfWriter.getInstance(generatedDocument, baos);
generatedDocument.open();
document.setDocument(baos.toByteArray()); // stores as blob

I got value of null at database blob column.

Here's my Document domain object:

Document Domain Object

@Entity
@Table(name = "document")
public class Document implements java.io.Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "document_id", nullable = false)
    private int documentId;
    @Column(name = "document_name", nullable = false, length = 65535)
    private String documentName;
    @Column(name = "document_type", nullable = false)
    private int documentType;
    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "upload_date", nullable = false, length = 19)
    private Date uploadDate = new Date();
    @Column(name = "document", nullable = false)
    private byte[] document;    // BLOB COLUMN
    @Column(name = "document_size", nullable = false)
    private long documentSize;
    @Column(name = "title", nullable = true, insertable = true, updatable = true, length = 65535, precision = 0)
    private String title;
    @Column(name = "tag", nullable = true, insertable = true, updatable = true, length = 65535, precision = 0)
    private String tag;
    @Column(name = "description", nullable = true, insertable = true, updatable = true, length = 65535, precision = 0)
    private String description;
    @Column(name = "shared", nullable = false, insertable = true, updatable = true, length = 1, precision = 0)
    private boolean shared = false;
    @Column(name = "status", nullable = false)
    private int status = DocumentStatus.READY.getStatus();


    public int getDocumentId() {
        return this.documentId;
    }

    public void setDocumentId(int documentId) {
        this.documentId = documentId;
    }

    public String getDocumentName() {
        return this.documentName;
    }

    public void setDocumentName(String documentName) {
        this.documentName = documentName;
    }

    public int getDocumentType() {
        return this.documentType;
    }

    public void setDocumentType(int documentType) {
        this.documentType = documentType;
    }

    public Date getUploadDate() {
        return this.uploadDate;
    }

    public void setUploadDate(Date uploadDate) {
        this.uploadDate = uploadDate;
    }

    public byte[] getDocument() {
        return this.document;
    }

    public void setDocument(byte[] document) {
        this.document = document;
    }

    public long getDocumentSize() {
        return this.documentSize;
    }

    public void setDocumentSize(long documentSize) {
        this.documentSize = documentSize;
    }

    public String getTag() {
        return tag;
    }

    public void setTag(String tag) {
        this.tag = tag;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public boolean getShared() {
        return shared;
    }

    public void setShared(boolean shared) {
        this.shared = shared;
    }


    public int getStatus() {
        return status;
    }

    public void setStatus(int status) {
        this.status = status;
    }


}
like image 492
talha06 Avatar asked Aug 10 '12 07:08

talha06


2 Answers

Just updating the answer for the iText 7 version.

private static byte[] createPDF() {
    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
    PdfWriter writer = new PdfWriter(byteArrayOutputStream);
    PdfDocument pdfDocument = new PdfDocument(writer);
    Document document = new Document(pdfDocument);

    //Write the file content

    document.close();
    return byteArrayOutputStream.toByteArray();
}
like image 81
Guilherme Gehling Avatar answered Oct 05 '22 10:10

Guilherme Gehling


I had a similar problem... I'd create the Document and inside the class where I created it, I could save it to File, and it worked great. However, when I tried to return it as a Stream I would get a null value.

The problem was that once the Document was closed (document.close()), it would close the Stream also.

The work-around was to create a ByteArrayOutputStream when I created the Document and have the PdfWriter output to it. I could then do whatever I wanted with the PDF bytes... in my case I converted them to a StreamedContent to send to the user.

Create a variable to hold the bytes:

  private ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();

Have the PdfWriter output the data to the byte[] as it creates the document:

  Document document = new Document(PageSize.LETTER, 0.75F, 0.75F, 0.75F, 0.75F);
  PdfWriter.getInstance(document, byteArrayOutputStream);  // Do this BEFORE document.open()

  document.open();
  createPDF(document);  // Whatever function that you use to create your PDF
  document.close();

Once you're done generating the PDF, just get the Bytes and do with them as you will.

  byte[] pdfBytes = byteArrayOutputStream.toByteArray();

I don't know what your reportService class looks like, but this may be a good place to put it.

Hope this helps.

like image 24
AceFunk Avatar answered Oct 05 '22 11:10

AceFunk