2012-01-18 144 views
14

如何在链接中下载PDF文件?如何使用pdfbox生成可下载PDF(损坏的PDF)?

我使用JSF构建Web应用程序,当在“保存为PDF”用户点击链接PDF应该是可供下载。

到目前为止,我有一个生成PDF文件的工作代码,但该文件保存在我的桌面上,我想要做的是,当用户点击链接时,PDF文件应该可下载而不是存储在应用程序中。

更新3: 谢谢您的帮助球员,我体改我的代码以您的建议和它的工作。

更新2: 我收到以下错误:Adoble阅读器无法打开“yourfile.pdf”,因为要么是不支持的文件类型,或者因为文件已损坏

更新1: 我加入我当前的代码与你指着我让的变化,但是我仍然在努力使这项工作

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

我不知道,因为当我试图打开我得到了错误的PDF什么,我缺少的:Adoble阅读器无法打开“yourfile.pdf”,因为无论是不是支持的文件类型或因为文件已损坏

+0

重新“更新2”,这可能是这个bug:http://issues.apache.org/jira/browse/PDFBOX-2026。它将在1.8.5中修复。或者下载快照。 – 2014-04-16 10:46:05

+0

你好@晚上。我试图实现类似于你所完成的事情。您能否将响应对象声明放入您的servlet中?或者可能发布整个代码? – Erick 2016-05-24 01:46:01

回答

7

您需要设置正确的http头以告诉浏览器下载文件。

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

我添加了一个示例代码,我的问题也是我加入了头,但我得到试图打开PDF文件时出现以下错误: Adob​​le阅读器无法打开“yourfile.pdf”,因为要么是不支持的文件类型或因该文件已被损坏。 – 2012-01-18 17:30:20

+0

“yourfile。pdf“应该是一个你正在生成的文件名,我只把它作为一个样本名称,尝试删除反斜杠和引号 – jloper3 2012-01-18 19:49:41

+0

response.addHeader(”Content-Disposition“,”attachment; filename = yourFile.pdf“) – jloper3 2012-01-18 19:50:41

4

我一段时间没有这样做,请耐心等待,但是您所做的是不是通过流将pdf保存到文件,而是将流保存在内存中作为字节数组,然后当用户单击链接时,将MIME类型设置为PDF,然后将字节数组作为流返回,作为re sponse。对于细节上有点朦胧,我表示抱歉。我想我也用jpedal和iText来完成它。

我不能告诉你所有的代码,但这里是一些:

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

然后你可以写出来的BAOS作为使用正确的MIME类型的PDF你的反应。

+0

我更新了我的问题,并根据您的回复修改了我的代码。 – 2012-01-18 17:21:27