iText generated PDF not shown correctly in Chrome

2019-03-04 07:15发布

问题:

I am using the iText library in Java to generate a pdf file. The idea is that a user fills in some information and that when the user clicks on the generate button the pdf is shown in a new tab in the browser. Now I have stumbled upon some problems doing this, which are : - the URL does not change, so instead of /application/user.pdf I get /application/dashboard.xhtml - I can save the pdf file in all browsers except for Chrome.

Please note that I don't want to save it on disc but simply show the pdf in the browser so the user can choose if he wants to save it.

Here is the code that I use to generate my pdf :

     public static void createPdf(User user, byte languageNumber, HttpServletResponse   response) {
Document document = new Document();
    try {
        /*    PdfWriter writer = PdfWriter.getInstance(document,
 new FileOutputStream("c://" + user.getUsername() + "_" + languageCode + ".pdf"));*/
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        PdfWriter.getInstance(document, baos);
        document.addTitle("Your CV");
        document.addSubject("This is your CV");
        document.addKeywords("CV");
        document.addAuthor(user.getUsername());
        document.open();
        document.add(
                new Paragraph(user.getPersonalInformation().getFirstname() + " " +    user.getPersonalInformation().getLastname()));
        document.close();
        // setting some response headers
        response.setHeader("Expires", "0");
        response.setHeader("Cache-Control",
            "must-revalidate, post-check=0, pre-check=0");
        response.setHeader("Pragma", "public");
        // setting the content type
        response.setContentType("application/pdf");
        response.setContentLength(baos.size());
        //ServletOutputStream out = response.getOutputStream();
        OutputStream out = response.getOutputStream();
        baos.writeTo(out);
        out.flush();
        out.close();
    } catch (DocumentException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
    }
}

*This method is behind a button on my JSF page *

public String exportPdf() {
    user = userService.retrieveLoginUser();
    FacesContext context = FacesContext.getCurrentInstance();
    try {
        Object response = context.getExternalContext().getResponse();
        if (response instanceof HttpServletResponse) {
            HttpServletResponse hsr = (HttpServletResponse) response;
            PdfCreator.createPdf(user, selectLanguage, hsr);
            //Tell JSF to skip the remaining phases of the lifecycle
            context.responseComplete();
        }
        return "../" + user.getUsername() + ".pdf";
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}

Used technologies : - JSF 2.0 - Facelets - iText

Thanks in advance :D

回答1:

The way that I have achieved this in the past is by creating a seperate Servlet to serve PDF documents directly. In the web.xml file you would specify the servlet mapping to *.pdf.

What you can do then is rather than override the FacesServlet response bytes to server the PDF file you just redirect the response to filename.pdf, passing needed parameters in the URL.

Your PDF servlet can actually do the work of building the necessary PDF, it will open in a seperate tab and the URL will match the response redirect.



回答2:

Does chrome open the PDF and then not render it correctly? In that case, please open an issue at http://new.crbug.com and attach an example PDF file that shows the problem. Reply with the issue number here.