Zurückgegebenes PDF mit Feder MVC zurückgeben

71

Ich verwende Spring MVC. Ich muss einen Dienst schreiben, der Eingaben vom Anforderungshauptteil entgegennimmt, die Daten zum PDF hinzufügt und die PDF-Datei an den Browser zurückgibt. Das PDF-Dokument wird mit itextpdf erstellt. Wie kann ich das mit Spring MVC machen? Ich habe versucht, dies zu verwenden

@RequestMapping(value="/getpdf", method=RequestMethod.POST)
public Document getPDF(HttpServletRequest request , HttpServletResponse response, 
      @RequestBody String json) throws Exception {
    response.setContentType("application/pdf");
    response.setHeader("Content-Disposition", "attachment:filename=report.pdf");
    OutputStream out = response.getOutputStream();
    Document doc = PdfUtil.showHelp(emp);
    return doc;
}

showhelp-Funktion, die das PDF generiert. Ich füge vorerst nur einige zufällige Daten ins PDF ein.

public static Document showHelp(Employee emp) throws Exception {
    Document document = new Document();

    PdfWriter.getInstance(document, new FileOutputStream("C:/tmp/report.pdf"));
    document.open();
    document.add(new Paragraph("table"));
    document.add(new Paragraph(new Date().toString()));
    PdfPTable table=new PdfPTable(2);

    PdfPCell cell = new PdfPCell (new Paragraph ("table"));

    cell.setColspan (2);
    cell.setHorizontalAlignment (Element.ALIGN_CENTER);
    cell.setPadding (10.0f);
    cell.setBackgroundColor (new BaseColor (140, 221, 8));                                  

    table.addCell(cell);                                    
    ArrayList<String[]> row=new ArrayList<String[]>();
    String[] data=new String[2];
    data[0]="1";
    data[1]="2";
    String[] data1=new String[2];
    data1[0]="3";
    data1[1]="4";
    row.add(data);
    row.add(data1);

    for(int i=0;i<row.size();i++) {
      String[] cols=row.get(i);
      for(int j=0;j<cols.length;j++){
        table.addCell(cols[j]);
      }
    }

    document.add(table);
    document.close();

    return document;   
}

Ich bin sicher, das ist falsch. Ich möchte, dass das PDF generiert und das Dialogfeld zum Speichern / Öffnen über den Browser geöffnet wird, damit es im Dateisystem des Clients gespeichert werden kann. Bitte hilf mir.

Maheshwaran K.
quelle

Antworten:

128

Sie waren mit auf dem richtigen Weg response.getOutputStream(), aber Sie verwenden die Ausgabe nirgendwo in Ihrem Code. Im Wesentlichen müssen Sie die Bytes der PDF-Datei direkt in den Ausgabestream streamen und die Antwort leeren. Im Frühling können Sie es so machen:

@RequestMapping(value="/getpdf", method=RequestMethod.POST)
public ResponseEntity<byte[]> getPDF(@RequestBody String json) {
    // convert JSON to Employee 
    Employee emp = convertSomehow(json);

    // generate the file
    PdfUtil.showHelp(emp);

    // retrieve contents of "C:/tmp/report.pdf" that were written in showHelp
    byte[] contents = (...);

    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.APPLICATION_PDF);
    // Here you have to set the actual filename of your pdf
    String filename = "output.pdf";
    headers.setContentDispositionFormData(filename, filename);
    headers.setCacheControl("must-revalidate, post-check=0, pre-check=0");
    ResponseEntity<byte[]> response = new ResponseEntity<>(contents, headers, HttpStatus.OK);
    return response;
}

Anmerkungen:

  • Verwenden Sie aussagekräftige Namen für Ihre Methoden: Die Benennung einer Methode, die ein PDF-Dokument schreibt, showHelpist keine gute Idee
  • Lesen einer Datei in ein byte[]: Beispiel hier
  • Ich würde vorschlagen, dem Namen der temporären PDF-Datei eine zufällige Zeichenfolge hinzuzufügen showHelp(), um ein Überschreiben der Datei zu vermeiden, wenn zwei Benutzer gleichzeitig eine Anfrage senden
kryger
quelle
Das hat mir geholfen. Vielen Dank!!! Ich habe noch einen. Hier speichere ich das generierte PDF in meinem Dateisystem und lese es dann und konvertiere es in Bytes. Was soll ich tun, wenn ich das generierte PDF unterwegs konvertieren muss? Vielen Dank im Voraus
Maheshwaran K
7
Anstatt FileOutputStreamin Ihrem zu verwenden PdfWriter.getInstance(), könnten Sie ein verwenden ByteArrayOutputStream.
Kryger
@kryger, wissen Sie, wie man die PDF-Datei in einem Browserfenster öffnet? Ich habe Ihre Methode verwendet und ich fordere den Benutzer auf, die Datei sofort zu speichern :)
Warum eine Datei im Dateisystem speichern?
Cherouvim
2
Seit Spring 4.3 MediaType.APPLICATION_PDFist als statische Variable verfügbar.
Przemek Nowak