2012-01-18 4 views
14

Comment créer un fichier PDF téléchargeable dans un lien?Comment générer un fichier PDF téléchargeable avec pdfbox (PDF corrompu)?

Je construis une application web en utilisant JSF, quand l'utilisateur clique dans un lien "Enregistrer en PDF" un PDF devrait être disponible pour être téléchargé. Jusqu'à présent, j'ai un code de travail qui génère le fichier PDF, mais le fichier est enregistré sur mon bureau et ce que je veux faire est que lorsque l'utilisateur clique sur le lien, le fichier pdf devrait être téléchargeable au lieu d'être stocké dans l'application.

MISE À JOUR 3: Merci pour votre aide les gars, je modifed mon code avec vos suggestions et il fonctionne.

MISE À JOUR 2: Je reçois l'erreur suivante: Adoble Reader ne pouvait ouvrir « yourfile.pdf » car est soit pas un type de fichier pris en charge ou parce que le fichier a été endommagé

MISE à JOUR 1: J'ajoute mon code actuel avec les changements que vous me l'avez signalé, mais je suis encore du mal à faire ce travail

This is my method that generated the PDF:

public ByteArrayOutputStream createPDF() throws IOException, COSVisitorException { 

    PDDocument document; 
    PDPage page; 
    PDFont font; 
    PDPageContentStream contentStream; 
    PDJpeg front; 
    PDJpeg back; 

    InputStream inputFront; 
    InputStream inputBack; 
    ByteArrayOutputStream output = new ByteArrayOutputStream(); 

    // Creating Document 
    document = new PDDocument(); 

    // Creating Pages 
    for(int i=0; i<2; i++) { 

     page = new PDPage(); 

     // Adding page to document 
     document.addPage(page); 

     // Adding FONT to document 
     font = PDType1Font.HELVETICA;   

     // Retrieve Image to be added to the PDF 
     inputFront = new FileInputStream(new File("D:/Media/imageFront.jpg")); 
     inputBack = new FileInputStream(new File("D:/Media/imageBack.jpg")); 

     BufferedImage buffFront = ImageIO.read(inputFront); 
     BufferedImage resizedFront = Scalr.resize(buffFront, 460); 

     BufferedImage buffBack = ImageIO.read(inputBack); 
     BufferedImage resizedBack = Scalr.resize(buffBack, 460); 

     front = new PDJpeg(document, resizedFront); 
     back = new PDJpeg(document, resizedBack); 

     // Next we start a new content stream which will "hold" the to be created content. 
     contentStream = new PDPageContentStream(document, page);     

     // Let's define the content stream 
     contentStream.beginText(); 
     contentStream.setFont(font, 8); 
     contentStream.moveTextPositionByAmount(10, 770); 
     contentStream.drawString("Amount: $1.00"); 
     contentStream.endText(); 

     contentStream.beginText(); 
     contentStream.setFont(font, 8); 
     contentStream.moveTextPositionByAmount(200, 770); 
     contentStream.drawString("Sequence Number: 123456789"); 
     contentStream.endText(); 

     contentStream.beginText(); 
     contentStream.setFont(font, 8); 
     contentStream.moveTextPositionByAmount(10, 760); 
     contentStream.drawString("Account: 123456789"); 
     contentStream.endText(); 

     contentStream.beginText(); 
     contentStream.setFont(font, 8); 
     contentStream.moveTextPositionByAmount(200, 760); 
     contentStream.drawString("Captura Date: 04/25/2011"); 
     contentStream.endText(); 

     contentStream.beginText(); 
     contentStream.setFont(font, 8); 
     contentStream.moveTextPositionByAmount(10, 750); 
     contentStream.drawString("Bank Number: 123456789"); 
     contentStream.endText(); 

     contentStream.beginText(); 
     contentStream.setFont(font, 8); 
     contentStream.moveTextPositionByAmount(200, 750); 
     contentStream.drawString("Check Number: 123456789"); 
     contentStream.endText();    

     // Let's close the content stream  
     contentStream.close(); 

    } 

    // Finally Let's save the PDF 
    document.save(output); 
    document.close(); 

    return output; 
} 

This is my servlet that call the previous code and generates the output and set the header:

try { 

     ByteArrayOutputStream output = new ByteArrayOutputStream(); 
     output = createPDF(); 

     response.addHeader("Content-Type", "application/force-download"); 
     response.addHeader("Content-Disposition", "attachment; filename=\"yourFile.pdf\""); 
     response.getOutputStream().write(output.toByteArray()); 

    } catch (Exception ex) {    
     ex.printStackTrace(); 
    } 

Je ne suis pas sûr de ce que je suis absent depuis quand je tente d'ouvrir le fichier PDF que je suis l'erreur: Adoble lecteur n'a pas pu ouvrir « yourfile.pdf » parce que c'est soit pas Type de fichier pris en charge ou parce que le fichier a été endommagé

+0

Re "Mise à jour 2", cela pourrait être ce bug: http://issues.apache.org/jira/browse/PDFBOX-2026. Ce sera corrigé en 1.8.5. Ou téléchargez un instantané. –

+0

Bonjour @Night. J'essaie de mettre en œuvre quelque chose de similaire à ce que vous avez accompli. Pourriez-vous s'il vous plaît mettre la déclaration de l'objet de réponse à l'intérieur de votre servlet? Ou peut-être afficher l'intégralité du code? – Erick

Répondre

7

Vous devez définir les en-têtes http appropriés pour indiquer au navigateur de télécharger le fichier.

response.addHeader("Content-Type", "application/force-download") 
response.addHeader("Content-Disposition", "attachment; filename=\"yourFile.pdf\"") 
+0

J'ai ajouté un exemple de code à ma question aussi j'ai ajouté les en-têtes mais j'ai l'erreur suivante en essayant d'ouvrir le fichier PDF: Adoble Reader n'a pas pu ouvrir "yourfile.pdf" parce que ce n'est pas un type de fichier supporté ou parce que le fichier a été endommagé. –

+0

Le fichier "yourfile".pdf "devrait être un nom de fichier que vous générez.J'ai seulement inclus cela comme un exemple de nom.Essayez de supprimer les barres obliques inverses et les citations – jloper3

+0

response.addHeader (" Content-Disposition "," pièce jointe; filename = yourFichier.pdf ") – jloper3

4

Je ne l'ai pas fait depuis un moment, alors gardez avec moi, mais ce que vous faites est de sauvegarder le fichier pdf dans un fichier via un flux, vous enregistrez le flux dans la mémoire en tant que tableau d'octets, puis lorsque l'utilisateur clique sur le lien, définissez le type MIME sur PDF, puis ouvrez le tableau d'octets sous la forme d'un flux que vous renvoyez réponse. Je m'excuse d'être un peu brumeux sur les détails. Je pense que j'ai aussi utilisé jpedal et iText pour le faire.

Je ne peux pas vous montrer tout le code, mais voici quelques:

import com.itextpdf.text.BaseColor; 
import com.itextpdf.text.Document; 
import com.itextpdf.text.DocumentException; 
import com.itextpdf.text.Paragraph; 
import com.itextpdf.text.Phrase; 
import com.itextpdf.text.pdf.PdfPCell; 
import com.itextpdf.text.pdf.PdfPTable; 
import com.itextpdf.text.pdf.PdfWriter; 
import com.itextpdf.text.pdf.draw.DottedLineSeparator; 

... // class, etc. 

public ByteArrayOutputStream createOrderFormPdf(OrderFormDTO dto) 
     throws DocumentException { 
    Document document = new Document(); 
    ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
    PdfWriter.getInstance(document, baos); 
    document.open(); 

    Paragraph header = new Paragraph(); 
    header.add(new Phrase(...)); 

    OrderFormDtoPdfAdapter pdfAdapter = new OrderFormDtoPdfAdapter(dto); 
    header.add(pdfAdapter.getPdfHeaderTable()); 

    document.add(header); 

      ... // other code 

    Paragraph footer = new Paragraph(); 
    footer.add(pdfAdapter.getPDFFooterTable()); 

    document.add(footer); 
    Paragraph paragraph = new Paragraph(); 
    PdfTableUtils.addEmptyLine(paragraph, 2); 

    document.add(paragraph); 
    document.add(new DottedLineSeparator()); 

    document.close(); 

    return baos; 
} 

Vous pouvez alors écrire les baos sur votre réponse en pdf en utilisant le type MIME correct.

+0

J'ai mis à jour ma question avec une version modifiée de mon code en fonction de votre réponse. –

Questions connexes