0

我想问你如何从 Firefox 19 中的 servlet 输出 pdf 文件。

我有一个输出 pdf 流的 servlet

.....

public void doPost(HttpServletRequest request, HttpServletResponse response) {




    try {

        String namePDF = "filename.pdf";
        StringBuffer sb = new StringBuffer(request.getScheme());
        sb.append("://").append(request.getServerName());
        if (request.getServerPort() > 0) {
            sb.append(":").append(request.getServerPort());
        }
        sb.append(request.getContextPath()).append("/dirPdf/")
                .append(namePDF);

        OutputStream out = response.getOutputStream();

        Document document = new Document();
        document.setMargins(30, 30, 25, 25);

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        PdfWriter pdfWriter = PdfWriter.getInstance(document, baos);

        PdfPageEvents events = new PdfPageEvents();
        pdfWriter.setPageEvent(events);

        // step 2: we set the ContentType and create an instance of the
        // corresponding Writer
        // writer.setEncryption(null, null, PdfWriter.ALLOW_PRINTING,
        // PdfWriter.STANDARD_ENCRYPTION_40);




        document.open();

        compiledModule(request, response, document);


        document.newPage();
        pdfWriter.setPageEmpty(false);

        // chiudo il documento
        document.close();

        int tot = pdfWriter.getPageNumber() - 1;


        PdfReader reader = new PdfReader(baos.toByteArray());
        reader.consolidateNamedDestinations();
        PdfStamper pdfStamper = new PdfStamper(reader,baos);

        //read from module
        reader = new PdfReader(sb.toString());
        reader.consolidateNamedDestinations();

        PdfContentByte cbu = pdfStamper.getUnderContent(tot);
        PdfImportedPage page = pdfStamper.getImportedPage(reader, 2);

        cbu.addTemplate(page, 1, 0, 0, 1, 0, 0);

        pdfStamper.close();

        response.setContentType("application/pdf");
        response.setContentLength(baos.size());
        response.setBufferSize(baos.size());

        baos.writeTo(out);
        out.flush();
        out.close();
    } catch (Exception e) {

        logger.error("", e);
        try {
            /*if (out != null)
                out.close();*/
            response.sendRedirect("../exception.jsp?message="
                    + e.getMessage());
        } catch (IOException ex) {
            logger.error("", ex);
        }
    }
}

....

在 Internet Explorer 和 Chrome 中正确查看文件,而在 Firefox 19 中出现以下错误

“此 PDF 文档可能无法正确显示”

我知道有一个解决方案可以通过更改 Firefox 19 中的设置来实现,无论如何,因为我的应用程序的许多用户可能会因此而气馁,最好知道是否有实用的解决方法让 Firefox 显示的PDF。

或者也许这是一个没有解决方法的错误?

先感谢您!

--- 更新 28/02/2013 下午 12:52 ---

这个问题似乎与我使用一些 ByteArrayOutputStream 复制到输出流的事实有关。如果我直接使用 outputStream 一切正常。不幸的是,我不得不使用 ByteArrayOutputStream,因为我必须将 pdf 的最后一页粘贴到另一页。

4

1 回答 1

0

我的情况的解决方案是更改并添加第二个 ByteArrayOutputStream

.....

public void doPost(HttpServletRequest request, HttpServletResponse response) {




try {

    String namePDF = "filename.pdf";
    StringBuffer sb = new StringBuffer(request.getScheme());
    sb.append("://").append(request.getServerName());
    if (request.getServerPort() > 0) {
        sb.append(":").append(request.getServerPort());
    }
    sb.append(request.getContextPath()).append("/dirPdf/")
            .append(namePDF);

    OutputStream out = response.getOutputStream();

    Document document = new Document();
    document.setMargins(30, 30, 25, 25);

    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    ByteArrayOutputStream baos2 = new ByteArrayOutputStream();
    PdfWriter pdfWriter = PdfWriter.getInstance(document, baos);

    PdfPageEvents events = new PdfPageEvents();
    pdfWriter.setPageEvent(events);

    // step 2: we set the ContentType and create an instance of the
    // corresponding Writer
    // writer.setEncryption(null, null, PdfWriter.ALLOW_PRINTING,
    // PdfWriter.STANDARD_ENCRYPTION_40);




    document.open();

    compiledModule(request, response, document);


    document.newPage();
    pdfWriter.setPageEmpty(false);

    // chiudo il documento
    document.close();

    int tot = pdfWriter.getPageNumber() - 1;


    PdfReader reader = new PdfReader(baos.toByteArray());
    reader.consolidateNamedDestinations();
    PdfStamper pdfStamper = new PdfStamper(reader,baos2);

    //read from module
    reader = new PdfReader(sb.toString());
    reader.consolidateNamedDestinations();

    PdfContentByte cbu = pdfStamper.getUnderContent(tot);
    PdfImportedPage page = pdfStamper.getImportedPage(reader, 2);

    cbu.addTemplate(page, 1, 0, 0, 1, 0, 0);

    pdfStamper.close();

    response.setContentType("application/pdf");
    response.setContentLength(baos2.size());
    response.setBufferSize(baos2.size());

    baos2.writeTo(out);
    out.flush();
    out.close();
} catch (Exception e) {

    logger.error("", e);
    try {
        /*if (out != null)
            out.close();*/
        response.sendRedirect("../exception.jsp?message="
                + e.getMessage());
    } catch (IOException ex) {
        logger.error("", ex);
    }
}

}

……

使用 PdfStamper 向自己添加 byteArrayOutputStream 似乎存在问题。我不明白只有一个宝和两个宝之间的联系。随意解释...

于 2013-02-28T13:20:40.267 回答