0

I use the Java Spring Boot framework and I need to convert my Json to PDF. The problem is that all text in the PDF is written in one line, which means that line breaks do not work. As a result, I get a PDF in which the first line is blank or an empty file.

 @GetMapping("/pdf/{Id}")
    @Secured({"ROLE_ADMIN", "ROLE_OPERATOR", "ROLE_GUEST"})
    public ResponseEntity<PDDocument> findOnePdfByIdJob(@PathVariable("Id") Long id) throws DocumentException, IOException {
        Job job = jobService.findById(id);

        if (job == null) {
            return new ResponseEntity<>(HttpStatus.NOT_FOUND);
        }

        ObjectMapper objectMapper = new ObjectMapper();
        String jsonInString = objectMapper.writeValueAsString(job);

        Gson gson = new GsonBuilder().setPrettyPrinting().create();
        JsonParser jp = new JsonParser();
        JsonElement je = jp.parse(jsonInString);
        String prettyJsonString = gson.toJson(je);


        PDDocument document = new PDDocument();
        PDPage page = new PDPage();
        document.addPage(page);

        PDPageContentStream contentStream = new PDPageContentStream(document, page);

        contentStream.setFont(PDType1Font.COURIER, 12);
        contentStream.beginText();
        contentStream.showText(jsonInString);
        contentStream.endText();
        contentStream.close();

        document.save("pdfBoxHelloWorld.pdf");
        document.close();

        HttpHeaders headers = new HttpHeaders();
        headers.add("Cache-Control", "no-cache, no-store, must-revalidate");
        headers.add("Pragma", "no-cache");
        headers.add("Expires", "0");

        return ResponseEntity.ok()
                .headers(headers)
                .contentType(MediaType.parseMediaType("application/octet-stream"))
                .body(document);
    }

As a result, I get a PDF in which everything is written in one line. That is, the text cannot be read .... The first line becomes just a blank line.

Woodchuck
  • 3,869
  • 2
  • 39
  • 70
user3391185
  • 33
  • 1
  • 1
  • 5

1 Answers1

1

You do not need to use Gson if you already use Jackson's ObjectMapper. Just enable SerializationFeature.INDENT_OUTPUT feature and ObjectMapper will generate pretty JSON as well. Also, you need split JSON on lines and add each line one by one using newLine method from PDPageContentStream.

Simple app:

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.type.MapType;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.font.PDType1Font;

import java.io.File;
import java.util.Map;

public class PdfApp {

    public static void main(String[] args) throws Exception {
        File jsonFile = new File("./resource/test.json").getAbsoluteFile();

        ObjectMapper mapper = new ObjectMapper();
        // enable pretty printing
        mapper.enable(SerializationFeature.INDENT_OUTPUT);

        // read map from file
        MapType mapType = mapper.getTypeFactory().constructMapType(Map.class, String.class, Object.class);
        Map<String, Object> map = mapper.readValue(jsonFile, mapType);

        // generate pretty JSON from map
        String json = mapper.writeValueAsString(map);
        // split by system new lines
        String[] strings = json.split(System.lineSeparator());

        PDDocument document = new PDDocument();
        PDPage page = new PDPage();
        document.addPage(page);

        PDPageContentStream contentStream = new PDPageContentStream(document, page);

        contentStream.setFont(PDType1Font.COURIER, 12);
        contentStream.beginText();
        contentStream.setLeading(14.5f);
        contentStream.newLineAtOffset(25, 725);
        for (String string : strings) {
            contentStream.showText(string);
            // add line manually
            contentStream.newLine();
        }
        contentStream.endText();
        contentStream.close();

        document.save("pdfBoxHelloWorld.pdf");
        document.close();
    }
}

Generates PDF file with content like below: enter image description here

See also:

Michał Ziober
  • 37,175
  • 18
  • 99
  • 146
  • Thank, but when i try to use this example it cannot find one of the fonts, if I understood correctly: 2019-03-23 19:48:30.701 ERROR 7700 --- [nio-8443-exec-2] o.a.p.p.font.FileSystemFontProvider : Could not load font file: C:\Windows\FONTS\mstmc.ttf When i debugging a program crashes on the line: contentStream.beginText (); – user3391185 Mar 23 '19 at 18:56