Home > Enterprise >  How to send PDF file on response
How to send PDF file on response

Time:06-02

I'm trying to write a web app that converts images to PDF file. The user sends a couple of images (JPEG, PNG) and should receive and download a PDF file.

The main problem, for now, is that I don't know how to return the PDF file back to the client.

Here is my controller:

    @PostMapping(path = "/upload",
            consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public void uploadFiles(@RequestParam("files") MultipartFile[] files) throws IOException {
        imageToPdfConversionService.convert(files);
    } 

This is the service that converts images to PDF file (here I'm using itextpdf library):

public void convert(MultipartFile[] files) throws IOException {

        List<ImageData> imagesData = Arrays.stream(files)
                .map(file -> {
                    try {
                        return ImageDataFactory.create(file.getBytes());
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                })
                .collect(Collectors.toList());

//        PdfDocument pdfDocument = new PdfDocument(new PdfWriter("ImageToPdf.pdf"));
        FileOutputStream fileOutputStream = new FileOutputStream("letspdf-server/src/main/resources/documents/file.pdf");
        PdfDocument pdfDocument = new PdfDocument(new PdfWriter(fileOutputStream));

        Document document = new Document(pdfDocument);

        for (ImageData image : imagesData) {
            Image img = new Image(image);
            img.setWidth(pdfDocument.getDefaultPageSize().getWidth() - 50);
            img.setAutoScaleHeight(true);
            document.add(img);
            pdfDocument.addNewPage();
        }
        pdfDocument.close();
    }

Also, maybe store a PDF file somewhere and create a 'Download' button on the client-side when a file is generated to download the file from storage?

CodePudding user response:

So first of all you need to change your api to return ResponseEntity and convert your resulted pdf into byte array. I'll attach a code snippet as an example

public static ResponseEntity<Resource> makeResponse(byte[] file, String filename, MultiValueMap<String, String> customHeaders) {
    MediaType mediaType = MediaType.APPLICATION_OCTET_STREAM;
    HttpHeaders headers = new HttpHeaders();
    if (StringUtils.isNotEmpty(filename)) {
        try {
            mediaType = MediaType.valueOf(MIME_TYPES.detect(filename));
        } catch (Exception var6) {
        }

        ContentDisposition contentDisposition = ContentDisposition.builder("attachment").filename(filename, StandardCharsets.UTF_8).build();
        headers.setAccessControlExposeHeaders(ACCESS_CONTROL_EXPOSE_HEADERS);
        headers.setContentDisposition(contentDisposition);
    }

    if (customHeaders != null && !customHeaders.isEmpty()) {
        headers.addAll(customHeaders);
    }

    ByteArrayResource body = null;
    if (file != null) {
        body = new ByteArrayResource(file);
    }

    return ((BodyBuilder)ResponseEntity.ok().headers(headers)).contentType(mediaType).body(body);
}
  • Related