准备工作
引用pom
<!--生成pdf-->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.11</version>
</dependency>
<!--中文字体-->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext-asian</artifactId>
<version>5.2.0</version>
</dependency>
<!--html xml 转为pdf-->
<dependency>
<groupId>com.itextpdf.tool</groupId>
<artifactId>xmlworker</artifactId>
<version>5.5.11</version>
</dependency>
1. 添加表格
创建两列的表格PdfPTable table = new PdfPTable(2);
如果要划定两列的比例,在后面添加一行
table.setWidths(new float[]{1, 3});
程序会自动添加格子,由于定义了每行两列,则两组为一行
PdfPCell 为每个格子,可以定义格子的样式,前后间距,边框样式等
一定要在cell的维度设置格式,table维度是不起效果的
如果只要最外面的边框,则需要多定义一个外圈的table, 原来的table作为外圈的cell填充进去
private void createTable(Document document, Font fontBig, Font fontNormal, Font fontYellow) {
try {
PdfPTable tableFather = new PdfPTable(1);//为了做外圈的边框
tableFather.setWidthPercentage(100);
PdfPTable table = new PdfPTable(2);
table.addCell(getCell("日期", 1, 1, fontYellow));
table.addCell(getCell("天气", 1, 1, fontYellow));
table.addCell(getCell("07.12", 1, 1, fontNormal));
table.addCell(getCell("下雨", 1, 1, fontNormal));
table.addCell(getCell("07.13", 1, 1, fontNormal));
table.addCell(getCell("多云", 1, 1, fontNormal));
Paragraph weatherParagraph = new Paragraph("天气信息", fontBig);
weatherParagraph.setSpacingAfter(10);
document.add(weatherParagraph);
PdfPCell tableItem = new PdfPCell(table);
tableItem.setBorderWidth(2f);
tableItem.setBorderColor(new BaseColor(227, 230, 232));
tableItem.setPadding(8f);
tableFather.addCell(tableItem);
document.add(tableFather);
} catch (Exception ex) {
}
}
private PdfPCell getCell(String cellValue, int colspan, int rowSpan, Font font) {
PdfPCell cell = new PdfPCell();
try {
cell = new PdfPCell(new Phrase(cellValue, font));
cell.setBorder(Rectangle.NO_BORDER);
cell.setPaddingTop(2f);
cell.setRowspan(rowSpan);
cell.setColspan(colspan);
cell.setHorizontalAlignment(Element.ALIGN_LEFT);
} catch (Exception ex) {
logger.warn("Pdf getCell Exception", 0, ex);
}
return cell;
}
类似效果图
itext生成的pdf会默认表格都在一行展示,如果展示不下,则在下一页分页展示,所以第一页展示不下会导致第一页末尾留下大段空白,很不美观。
尤其是在表格嵌套表格的情况下,之所以嵌套表格,是因为要保留最外侧的边框,去除内部的边框。
如何控制分页展示table,显得紧凑些?在add到document之前添加跨页设置
tableFather.setSplitLate(false);//跨页处理
tableFather.setSplitRows(true);
document.add(tableFather);
2. html添加
private void createHtml(Document document){
try {
String pocketDescription = "<html><body><p class=\"\" style=\"\">如果说荷兰是橙色的,那阿姆斯特丹就是缤纷的彩色。</p> <p class=\"\" style=\"\"><strong>游玩建议</strong><br>游玩整个阿姆斯特丹大约需2-3天</p></body></html>";
Paragraph context = new Paragraph();
ElementList elementList = MyXMLWorkerHelper.parseToElementList(pocketDescription, null);
for (Element element : elementList) {
context.add(element);
}
context.setSpacingBefore(10f);
document.add(context);
}
catch (Exception ex){
}
}
这里由于中文的关系,需用重载parseToElementList函数
public class MyXMLWorkerHelper {
public static class MyFontsProvider extends XMLWorkerFontProvider {
public MyFontsProvider() {
super(null, null);
}
@Override
public Font getFont(final String fontname, String encoding, float size, final int style) {
try {
BaseFont bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);//中文字体
return new Font(bfChinese, size, style);
} catch (Exception ex) {
return new Font(Font.FontFamily.UNDEFINED, size, style);
}
}
}
public static ElementList parseToElementList(String html, String css) throws IOException {
// CSS
CSSResolver cssResolver = new StyleAttrCSSResolver();
if (css != null) {
CssFile cssFile = XMLWorkerHelper.getCSS(new ByteArrayInputStream(css.getBytes()));
cssResolver.addCss(cssFile);
}
// HTML
MyFontsProvider fontProvider = new MyFontsProvider();
CssAppliers cssAppliers = new CssAppliersImpl(fontProvider);
HtmlPipelineContext htmlContext = new HtmlPipelineContext(cssAppliers);
htmlContext.setTagFactory(Tags.getHtmlTagProcessorFactory());
htmlContext.autoBookmark(false);
// Pipelines
ElementList elements = new ElementList();
ElementHandlerPipeline end = new ElementHandlerPipeline(elements, null);
HtmlPipeline htmlPipeline = new HtmlPipeline(htmlContext, end);
CssResolverPipeline cssPipeline = new CssResolverPipeline(cssResolver, htmlPipeline);
// XML Worker
XMLWorker worker = new XMLWorker(cssPipeline, true);
XMLParser p = new XMLParser(worker);
html = html.replace("<br>", "<br/>").replace("<hr>", "<hr/>").replace("<img>", "").replace("<param>", "").replace("<link>", "");//不支持单独标签
p.parse(new ByteArrayInputStream(html.getBytes()));
return elements;
}
}
类似效果