【问题标题】:Add padding to table cells using iTextPdf使用 iTextPdf 向表格单元格添加填充
【发布时间】:2016-08-23 13:51:34
【问题描述】:

以下是从 HTML 源生成 PDF 文档的演示代码:

public class SimpleAdhocReport
{
public SimpleAdhocReport()
{
    build();
}

private void build()
{
    AdhocConfiguration configuration = new AdhocConfiguration();
    AdhocReport report = new AdhocReport();
    configuration.setReport(report);

    AdhocColumn column = new AdhocColumn();
    column.setName("item");
    report.addColumn(column);

    column = new AdhocColumn();
    column.setName("orderdate");
    report.addColumn(column);

    column = new AdhocColumn();
    column.setName("quantity");
    report.addColumn(column);

    column = new AdhocColumn();
    column.setName("unitprice");
    report.addColumn(column);

    try
    {
        AdhocManager.saveConfiguration(configuration, new FileOutputStream("d:/configuration.xml"));
        @SuppressWarnings("unused")
        AdhocConfiguration loadedConfiguration = AdhocManager.loadConfiguration(new FileInputStream("d:/configuration.xml"));

        JasperReportBuilder reportBuilder = AdhocManager.createReport(configuration.getReport());
        reportBuilder.setDataSource(createDataSource());

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        reportBuilder.toHtml(baos);
        String html = new String(baos.toByteArray(), "UTF-8");
        baos.close();

        Whitelist wl = Whitelist.simpleText();
        wl.addTags("table", "tr", "td");
        String clean = Jsoup.clean(html, wl);

        clean = clean.replace("<td></td>", "");
        clean = clean.replace("<td> </td>", "");
        clean = clean.replace("<td> ", "<td>");

        Document doc = Jsoup.parse(clean);
        for (Element element : doc.select("*"))
        {
            if (!element.hasText() && element.isBlock())
            {
                element.remove();
            }
        }

        clean = doc.body().html();

        int startIndex = clean.indexOf("<table>", 6);
        int endIndex = clean.indexOf("</table>");
        clean = clean.substring(startIndex, endIndex + 8);

        BufferedWriter writer = new BufferedWriter(new FileWriter(("d:/test.html")));
        writer.write(clean);

        writer.close();

        try
        {
            createPdf(clean);
        }
        catch (DocumentException e)
        {
            e.printStackTrace();
        }

    }
    catch (DRException e)
    {
        e.printStackTrace();
    }
    catch (FileNotFoundException e)
    {
        e.printStackTrace();
    }
    catch (IOException e)
    {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

private JRDataSource createDataSource()
{
    DRDataSource dataSource = new DRDataSource("item", "orderdate", "quantity", "unitprice");
    for (int i = 0; i < 20; i++)
    {
        dataSource.add("Book", new Date(), (int) (Math.random() * 10) + 1,
                new BigDecimal(Math.random() * 100 + 1).setScale(4, BigDecimal.ROUND_HALF_UP));
    }
    return dataSource;
}

public static void main(String[] args)
{
    new SimpleAdhocReport();
}

public void createPdf(String html) throws IOException, DocumentException
{
    com.itextpdf.text.Document document = new com.itextpdf.text.Document(PageSize.LETTER);
    document.setMargins(30, 30, 80, 30);
    PdfWriter.getInstance(document, new FileOutputStream("D:\\HTMLtoPDF.pdf"));
    document.open();

    PdfPTable table = null;
    ElementList list = com.itextpdf.tool.xml.XMLWorkerHelper.parseToElementList(html, null);
    for (com.itextpdf.text.Element element : list)
    {
        table = new PdfPTable((PdfPTable) element);
    }
    table.setWidthPercentage(100);
    ArrayList<PdfPRow> rows = table.getRows();

    for (PdfPRow rw : rows)
    {
        PdfPCell[] cells = rw.getCells();
        for (PdfPCell cl : cells)
        {
            cl.setVerticalAlignment(com.itextpdf.text.Element.ALIGN_MIDDLE);
            cl.setBorder(PdfPCell.NO_BORDER);
            cl.setNoWrap(true);
            cl.setPadding(10f);
            cl.setCellEvent(new MyCell());
        }
    }

    document.add(table);

    document.close();
}
}

class MyCell implements PdfPCellEvent
{
    public void cellLayout(PdfPCell cell, Rectangle position, PdfContentByte[] canvases)
    {
        float x1 = position.getLeft() - 2;
        float x2 = position.getRight() + 2;
        float y1 = position.getTop() + 2;
        float y2 = position.getBottom() - 2;
        PdfContentByte canvas = canvases[PdfPTable.LINECANVAS];
        canvas.rectangle(x1, y1, x2 - x1, y2 - y1);
        canvas.stroke();
    }
}

我正在使用 jasper 报告来创建临时报告并从那里生成 HTML。我必须从这个 HTML 生成一个 PDF。

我面临的几个问题,感谢任何帮助:

  1. 我正在设置

    table.setWidthPercentage(100);

对于带有表格的页面,它不起作用。

  1. 我必须增加列间距。尝试了布鲁诺建议的here。它不工作。我也尝试过使用here 的解决方案,但没有成功。参考。下图。

  2. 另外,如果我将单元格事件设置为默认值不起作用。

例如

table.getDefaultCell().setCellEvent()

有什么建议吗?

更新:

我的输出

【问题讨论】:

  • 您是否遇到任何错误?你试过调试代码吗?
  • 没有错误。 PDF正在生成。让我看看我是否可以添加生成的 PDF 的屏幕截图。
  • 不能用iReport设计器来设计页面使用吗?
  • @Isiva 我没有使用它。我正在使用 Jsoup 库来清除所有格式。结束 html 生成为 &lt;table&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td&gt;item&lt;/td&gt; &lt;td&gt;orderdate&lt;/td&gt; &lt;td&gt;quantity&lt;/td&gt; &lt;td&gt;unitprice&lt;/td&gt; &lt;/tr&gt; 像这样。
  • 看起来标签没有正确关闭。删除 JSOUP 清理并尝试一下,它可以工作,然后修复清理代码。我的意思是将 html 按原样传递给 jasper,看看它是否有效。

标签: java itext


【解决方案1】:

我能够通过以下方式解析 HTML 来获得所需的填充:

public PdfPTable getTable(String cleanHTML) throws IOException
{
    String CSS = "tr { text-align: center; } td { padding: 5px; }";

    CSSResolver cssResolver = new StyleAttrCSSResolver();
    CssFile cssFile = XMLWorkerHelper.getCSS(new ByteArrayInputStream(CSS.getBytes()));
    cssResolver.addCss(cssFile);

    // HTML
    HtmlPipelineContext htmlContext = new HtmlPipelineContext(null);
    htmlContext.setTagFactory(Tags.getHtmlTagProcessorFactory());

    // Pipelines
    ElementList elements = new ElementList();
    ElementHandlerPipeline pdf = new ElementHandlerPipeline(elements, null);
    HtmlPipeline html = new HtmlPipeline(htmlContext, pdf);
    CssResolverPipeline css = new CssResolverPipeline(cssResolver, html);

    // XML Worker
    XMLWorker worker = new XMLWorker(css, true);
    XMLParser p = new XMLParser(worker);
    p.parse(new ByteArrayInputStream(cleanHTML.getBytes()));

    return (PdfPTable) elements.get(0);
}

这解决了问题 2 中提到的问题。不再需要 Q3。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-01-26
    • 2015-10-02
    • 1970-01-01
    • 1970-01-01
    • 2011-11-20
    • 2017-10-31
    • 1970-01-01
    相关资源
    最近更新 更多