web-dev-qa-db-fra.com

Retourner le pdf généré en utilisant le ressort MVC

J'utilise Spring MVC. Je dois écrire un service qui prendrait les entrées du corps de la demande, ajoute les données au fichier PDF et renvoie le fichier PDF au navigateur. Le document pdf est généré en utilisant itextpdf. Comment puis-je faire cela en utilisant Spring MVC. J'ai essayé d'utiliser ceci

@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;
}

fonction showhelp qui génère le pdf. Je ne fais que mettre des données aléatoires dans le pdf pour l'instant.

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;   
}

Je suis sûr que c'est faux. Je veux que le pdf soit généré et que la boîte de dialogue de sauvegarde/ouverture soit ouverte via le navigateur, de manière à pouvoir être stockée dans le système de fichiers du client. Sil te plait aide moi.

55
Maheshwaran K

Vous étiez sur la bonne voie avec response.getOutputStream(), mais vous n'utilisez pas sa sortie dans votre code. Ce que vous devez faire est essentiellement de transférer les octets du fichier PDF directement dans le flux de sortie et de vider la réponse. Au printemps, vous pouvez le faire comme ceci:

@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;
}

Remarques:

  • utiliser des noms significatifs pour vos méthodes: nommer une méthode qui écrit un PDF document showHelp est pas une bonne idée
  • lire un fichier dans un byte[]: exemple ici
  • Je suggérerais d'ajouter une chaîne aléatoire au nom de fichier temporaire PDF à l'intérieur de showHelp() pour éviter de remplacer le fichier si deux utilisateurs envoient une demande en même temps).
103
kryger