【问题标题】:Cannot read pdf generated by iText无法读取 iText 生成的 pdf
【发布时间】:2013-03-03 10:41:23
【问题描述】:

这是我生成 pdf 的代码:

public String generateList( Group group, List<GroupTerm> terms, List<Child> children, int begin, int finish )
{
    String pathForList = "C:\\...\\List.pdf";

    File filePath = new File( pathForList );
    filePath.delete();

    try
    {

        Document document = new Document( PageSize.A4.rotate() );

        PdfWriter.getInstance( document, new FileOutputStream( pathForList ) );

        document.open();

        // CONTENT

        BaseFont helvetica = BaseFont.createFont( BaseFont.HELVETICA, BaseFont.CP1250, BaseFont.EMBEDDED );
        Font helvetica9 = new Font( helvetica, 9 );
        Font helvetica9bold = new Font( helvetica, 9, Font.BOLD );

        Paragraph paragraph1 =
            new Paragraph( "Godziny: " + group.getStartHours() + "-" + group.getFinishHours() + "  Miejsce: " + group.getPlace()
                + "  Grupa wiekowa: " + group.getAgeGroupName() + "  Poziom: " + group.getLevel() + "  Instruktor: " + group.getInstructor(),
                           helvetica9bold );

        paragraph1.setAlignment( Element.ALIGN_LEFT );

        document.add( paragraph1 );
        document.add( new Paragraph( " " ) ); 

        PdfPTable table = new PdfPTable( 12 ); // 12 columns.

        PdfPCell cell01 = new PdfPCell( new Paragraph( "Imię", helvetica9 ) );
        PdfPCell cell02 = new PdfPCell( new Paragraph( "Nazwisko", helvetica9 ) );
        table.addCell( cell01 );
        table.addCell( cell02 );

        for ( int i = begin; i < finish; i++ 
        {
            GroupTerm term = new GroupTerm();

            int iterator = -1;
            int a = i + 1;

            while ( term.getTermID() != a )
            {
                iterator++;
                term = terms.get( iterator );
            }

            table.addCell( new PdfPCell( new Paragraph( conv.dateFromCalToString( term.getTerm() ), helvetica9 ) ) );
        }

        for ( int j = 0; j < children.size(); j++ )
        {
            table.addCell( new PdfPCell( new Paragraph( children.get( j ).getName() ) ) );
            table.addCell( new PdfPCell( new Paragraph( children.get( j ).getSurname() ) ) );
            for ( int k = 0; k < 10; k++ )
            {
                table.addCell( new PdfPCell( new Paragraph( "" ) ) );
            }
        }

        document.add( table );

        document.close();
    }
    catch ( Exception e )
    {

    }

    return pathForList;
}

问题是这样的:我为某个数据生成 pdf,它创建 List.pdf,做得很好。但是,然后我尝试为另一组数据再生成一个,生成的文件大小为 0kb,打开时显示消息“Adobe Reader 无法打开”List.pdf”,因为它不是受支持的文件类型或因为文件已损坏”。

PDF 在我的网络应用程序中生成并通过 servlet 发送作为响应,因此我通过浏览器打开它。

编辑:我的 servlet 代码:

protected void doGet( HttpServletRequest request, HttpServletResponse response )
    throws ServletException, IOException
{
    ... // Getting data here

    String path = pdf.generateList( group, terms, children, begin, finish );

    // download

    response.setContentType( "application/octet-stream" );
    response.setHeader( "Content-Disposition", "attachment;filename=List.pdf" );

    ServletOutputStream out = null;

    try
    {
        File file = new File( path );
        FileInputStream fileIn = new FileInputStream( file );
        out = response.getOutputStream();

        byte[] outputByte = new byte[4096];
        // copy binary contect to output stream
        while ( fileIn.read( outputByte, 0, 4096 ) != -1 )
        {
            out.write( outputByte, 0, 4096 );
        }
        fileIn.close();
        out.flush();
        out.close();

        int i = 0;
    }
    catch ( Exception e )
    {
        if ( out != null )
        {
            out.close();
        }
    }
    finally
    {

    }

    response.sendRedirect( "calendar.jsp" );
}

编辑:我还在这个应用程序中使用 iText 生成发票,它工作正常。无论我使用什么数据,所有 pdf 文件都是正确的。

怎么了?我使用的是相同的方法,只是数据集不同。

【问题讨论】:

  • 如果出现问题,您将永远不会因为您的空catch ( Exception e ) 块而现在。
  • 文档是否关闭文件流?手动冲洗并关闭。
  • @jlordo:catch 只有简单的日志实现,它对我没有任何回报。 Michael-O:我在上面添加了我的 servlet 代码。调试时,如果流被关闭(关闭属性更改为 false->true)

标签: java pdf servlets itext


【解决方案1】:

尝试将您的内部循环替换为:

int got;
while ( (got = fileIn.read( outputByte, 0, 4096 )) > 0) {
    out.write( outputByte, 0, got );
}

您的原始循环始终在文件末尾写入 4096 个字节,但文件的最后一个块可能比这更短,因此您的原始循环在 HTTP 响应的末尾写了垃圾,将其填充为倍数4096 字节。

【讨论】:

  • 它没有帮助,但这个循环似乎比我的更合理,所以我会保留它。
  • 问题已解决。它是数据本身。方法无法正确获取数据,文件已损坏。我改变了发送数据的方式,它奏效了!
  • @eBEER:将其添加为答案并将其标记为已接受,因此人们现在无需阅读每条评论即可解决。
【解决方案2】:

问题解决了。它是数据本身。方法无法正确获取数据,文件已损坏。我改变了发送数据的方式,它奏效了!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-04
    • 1970-01-01
    • 1970-01-01
    • 2012-01-02
    • 1970-01-01
    相关资源
    最近更新 更多