2012-01-18 32 views
14

Làm cách nào để tạo tệp PDF có thể tải xuống trong liên kết?Cách tạo tệp PDF có thể tải xuống với pdfbox (PDF bị hỏng)?

Tôi đang xây dựng một ứng dụng web bằng JSF, khi người dùng nhấp vào liên kết "Lưu dưới dạng PDF", PDF sẽ sẵn có để tải xuống.

Cho đến nay tôi đã tạo mã làm việc để tạo tệp PDF nhưng tệp được lưu trên máy tính của tôi và những gì tôi muốn làm là khi người dùng nhấp vào liên kết, tệp pdf phải được tải xuống thay vì được lưu trữ trong ứng dụng.

CẬP NHẬT 3: Cảm ơn bạn đã giúp đỡ các bạn, tôi đã sửa đổi mã của tôi với các đề xuất của bạn và nó hoạt động.

UPDATE 2: Tôi nhận được lỗi sau: Adoble Reader không thể mở "yourfile.pdf" vì là một trong hai dạng tập tin không được hỗ trợ hoặc vì các tập tin đã bị hư hỏng

UPDATE 1: tôi thêm mã hiện tại của tôi với những thay đổi bạn đã chỉ cho tôi ra ngoài, tuy nhiên tôi vẫn đang đấu tranh để làm cho công việc này

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

Tôi không chắc chắn những gì tôi đang mất tích kể từ khi tôi cố gắng để mở tệp PDF Tôi đã nhận lỗi: Adoble Reader không thể mở "yourfile.pdf" vì là một trong hai không phải là một loại tệp được hỗ trợ hoặc vì tệp đã bị hỏng

+0

"Cập nhật 2", đây có thể là lỗi này: http://issues.apache.org/jira/browse/PDFBOX-2026. Nó sẽ được cố định trong 1.8.5. Hoặc tải xuống ảnh chụp nhanh. –

+0

Xin chào @Night. Tôi đang cố gắng thực hiện một cái gì đó tương tự như những gì bạn đã hoàn thành. Bạn có thể vui lòng đặt tuyên bố đối tượng phản hồi bên trong servlet của bạn không? Hoặc có thể đăng toàn bộ mã? – Erick

Trả lời

7

Bạn cần đặt tiêu đề http thích hợp để cho trình duyệt tải xuống tệp.

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

Tôi cũng đã thêm mã mẫu vào câu hỏi của mình nhưng tôi đã thêm tiêu đề nhưng tôi gặp lỗi sau khi cố gắng mở Tệp PDF: Trình đọc Adoble không thể mở "yourfile.pdf" vì không phải là loại tệp được hỗ trợ hoặc vì tệp đã bị hỏng. –

+0

"yourfile.pdf "nên là tên tệp bạn đang tạo. Tôi chỉ bao gồm tên tệp đó. Hãy thử xóa dấu gạch chéo ngược và dấu ngoặc kép. – jloper3

+0

response.addHeader (" Nội dung-Bố cục "," tệp đính kèm; filename = yourFile.pdf ") – jloper3

4

Tôi đã không thực hiện việc này trong một thời gian, vì vậy hãy mang theo, nhưng những gì bạn làm thay vì lưu tệp pdf vào tệp qua luồng, bạn lưu luồng trong bộ nhớ như một mảng byte và sau đó khi người dùng nhấp vào liên kết, bạn đặt loại MIME thành PDF và sau đó mở mảng byte dưới dạng luồng mà bạn quay trở lại làm lại sponse. Tôi xin lỗi vì hơi mơ hồ về chi tiết. Tôi nghĩ rằng tôi cũng sử dụng jpedal và iText để hoàn thành nó.

Tôi không thể cho bạn thấy tất cả các mã, nhưng đây là một số:

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

Sau đó bạn có thể viết ra những baos trên phản ứng của bạn như là một pdf bằng cách sử dụng định dạng MIME đúng.

+0

Tôi đã cập nhật câu hỏi của mình bằng phiên bản đã sửa đổi của mã dựa trên phản hồi của bạn. –

Các vấn đề liên quan