1

I've seen many answers here, I copied some examples and tried applying it, but I don't know how to make this work. I'm trying to create a file with PDFBox and sending it with a Response so the user can download it. So far, I'm able to download the file, but it is blank. I already tried just loading an example file from my computer with PDFBox and downloading it, but it comes the same way, blank. The code I am working with now is:

@GET
@Path("/dataPDF")
@Produces("application/pdf") 
public Response retrievePDF(){

        try {
                ByteArrayOutputStream output = new ByteArrayOutputStream();

                output = createPDF();
                ResponseBuilder response = Response.ok(output.toByteArray(), "application/pdf");
                response.header("Content-Disposition","attachment; filename=file.pdf");
                return response.build();
        } 
        catch (Exception ex) {                    
                ex.printStackTrace();
                return Response.status(Response.Status.NOT_FOUND).build();
        } 
public ByteArrayOutputStream createPDF() throws IOException {    
  
        PDFont font = PDType1Font.HELVETICA;
        PDPageContentStream contentStream;
        ByteArrayOutputStream output =new ByteArrayOutputStream();   
        PDDocument document =new PDDocument(); 
        PDPage page = new PDPage();
        document.addPage(page);
        contentStream = new PDPageContentStream(document, page);           
        contentStream.beginText();        
        contentStream.setFont(font, 20);        
        contentStream.newLineAtOffset(10, 770);        
        contentStream.showText("Amount: $1.00");        
        contentStream.endText();
        
        contentStream.beginText();        
        contentStream.setFont(font, 20);        
        contentStream.newLineAtOffset(200, 880);               
        contentStream.showText("Sequence Number: 123456789");        
        contentStream.endText();        
               
        contentStream.close(); 
           
        document.save(output);    
        document.close();    
        return output; 
      }

UPDATE 1: So the file is being created, now I'm justing having trouble sending it to the web, I'm using ReactJS. I tried adapting the structure I used to download a csv file, here it is:

const handleExportPDF= fileName => {
        FileController.retrievePDF().then((response) => {
            const url = window.URL.createObjectURL(new Blob([response.data]));
            const link = document.createElement('a');
            link.href = url;
            link.setAttribute('download', fileName);
            document.body.appendChild(link);
            link.click();
          });
        
    };
static retrievePDF() {
        const { method, url } = endpoints.retrievePDF();
        return api[method](url,{
            responseType: "application/pdf"
        });
    }
export const fileEndpoints = {
    retrievePDF: () => ({
        method: "get",
        url: `/export/dataPDF`
    })
};

UPDATE 2: If someone ever stumbles here, I was able to solve the problem with this answers here: PDF Blob - Pop up window not showing content. The point was changing

responseType: "application/pdf" to responseType: 'arraybuffer'

And even though it already works just changing this, I also changed

window.URL.createObjectURL(new Blob([response.data])); to window.URL.createObjectURL(new Blob([response.data]), {type: 'application/pdf'});

1 Answers1

1

With the Testcode below you can verify that your Sourcecode for PDF generation works in general.

But the positioning of the second Textelement is out of the Viewport.

Looks like your problem is related to the Webframework. You might give more details about this for further advice.

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<version>1.0-SNAPSHOT</version>

<properties>
    <maven.compiler.source>11</maven.compiler.source>
    <maven.compiler.target>11</maven.compiler.target>
</properties>

<dependencies>
    <dependency>
        <groupId>org.apache.pdfbox</groupId>
        <artifactId>pdfbox</artifactId>
        <version>2.0.19</version>
    </dependency>
</dependencies>

App.java

import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.font.PDFont;
import org.apache.pdfbox.pdmodel.font.PDType1Font;

import java.io.*;

public class App {

    public static void main(String[] args) throws  IOException {
        File resultFile = File.createTempFile("Test",".pdf");
        ByteArrayOutputStream byteArrayOutputStream = createPDF();
        try(OutputStream outputStream = new FileOutputStream(resultFile)) {
            byteArrayOutputStream.writeTo(outputStream);
        }
        System.out.println("Please find your PDF File here: " + resultFile.getAbsolutePath());
    }

    public static ByteArrayOutputStream createPDF() throws IOException {
        PDFont font = PDType1Font.HELVETICA;
        PDPageContentStream contentStream;
        ByteArrayOutputStream output =new ByteArrayOutputStream();
        PDDocument document =new PDDocument();
        PDPage page = new PDPage();
        document.addPage(page);
        contentStream = new PDPageContentStream(document, page);
        contentStream.beginText();
        contentStream.setFont(font, 20);
        contentStream.newLineAtOffset(10, 770);
        contentStream.showText("Amount: $1.00");
        contentStream.endText();

        contentStream.beginText();
        contentStream.setFont(font, 20);
        // 200 is way too much right and 800 too much on top... so this want be visible on normal A4 Format
        contentStream.newLineAtOffset(200, 880);
        contentStream.showText("Sequence Number: 123456789");
        contentStream.endText();

        contentStream.close();

        document.save(output);
        document.close();
        return output;
    }

}

enter image description here

Oliver
  • 332
  • 1
  • 11