使用iTextPdf向表格单元格添加填充

时间:2016-08-23 13:51:35

标签: java itext

以下是从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报告创建一个adhoc报告并从那里生成HTML。我必须从这个HTML生成PDF。

我面临的问题很多,感谢任何帮助:

  1. 我正在设置

    table.setWidthPercentage(100);

  2. 表格中的表格不起作用。

    1. 我必须增加列之间的间距。试过布鲁诺的建议here。它不起作用。我也试过使用here的解决方案而没有运气。参考。图片如下。

    2. 此外,如果i cell事件为默认值不起作用。

    3. e.g。

      table.getDefaultCell().setCellEvent()
      

      有什么建议吗?

      更新

      我的输出Generated PDF

1 个答案:

答案 0 :(得分:0)

我可以通过以下方式解析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。