Itext7 API总结
分辨率
大部分情况下,生成的pdf是有打印需求的,打印就涉及到pdf分辨率的问题。在itext中除了插入的图片外其他都是矢量图所以不必担心分辨率的问题,只需要保证插入图片的分辨率即可,在itext中生成图片的分辨率默认是72dpi,这里是需要做一些处理的,如下:
int defaultDpi = 72;
int targetDpi = 300;
Image test = new Image(ImageDataFactory.create("test.jpg"));
test.scale(defaultDpi/targetDpi, defaultDpi/targetDpi);
布局
绝对布局坐标原点在左下角
绝对布局
setFixedPosition(float left, float bottom, float width)
相对布局
使用相对布局时,不需要setFixedPosition,只需要设置距离上下左右的长度即可,这里感觉有点类似于css了。
setMarginLeft(float value);
setMarginRight(float value);
setMarginBottom(float value);
setMarginTop(float value);
setMargin(float commonMargin);
自动分页+生成页码
在使用绝对布局的时候,大部分情况下页面内容是固定大小的,位置也是固定的,分页也需要自己写代码来进行控制。但是如果pdf的内容不是固定的,这时候如果使用绝对布局就不是那么的灵活了,还需要自己计算元素的高度也设置绝对位置,这个时候我们选择使用相对布局则会更合适、简单一些。代码如下:
class PageEventHandler implements IEventHandler {
private Document document;
private PdfFont font;
//由于需要统一和汉字的字体,所以加了一个pdffont参数,没有此需求的可以不加
public PageEventHandler(Document document, PdfFont font){
this.document = document;
this.font = font;
}
@Override
public void handleEvent(Event event) {
PdfDocumentEvent pdfEvent = (PdfDocumentEvent) event;
PdfPage page = pdfEvent.getPage();
PdfDocument pdfDoc = pdfEvent.getDocument();
//获取当前页码
int pageNumber = pdfDoc.getPageNumber(page);
PdfCanvas pdfCanvas = new PdfCanvas(
page.newContentStreamBefore(), page.getResources(), pdfDoc);
//在距离上个元素50的距离处写页码
this.document.setTopMargin(50f);
pdfCanvas.beginText()
.setFontAndSize(this.font, 32)
//在页面一般宽的地方写上当前页面,由于字体定位的原点也在左下角,所以这里x轴减掉了页码宽度的一半,确保页码是写在中间的位置
//y轴是距离底部20px
.moveText(PageSize.A4.getWidth()/2-32/2, 20f)
.showText(String.valueOf(pageNumber))
.endText();
pdfCanvas.release();
}
}
//使用
pdfDocument.addEventHandler(PdfDocumentEvent.START_PAGE, new PageEventHandler(document, font));
常用组件
Table
//不指定table每一列的宽度,根据列的内容自适应
public Table(int numColumns);
//指定每一列的宽度
public Table(float[] pointColumnWidths);
//向table里面添加单元格,默认是横着加,达到指定列数后,自动换行
public Table addCell(Cell cell);
//设置table或cell的边框,这里需要注意,如果不想显示边框,需要在每一个cell中都设置border为none,只设置table的边框还是会显示边框的
public T setBorder(Border border);
//无边框
cell.setBorder(Border.NO_BORDER);
//实线边框
cell.setBorder(new SolidBorder(1));
//虚线边框
cell.setBorder(new DashedBorder(1));
//四个都是圆角
cell.setBorderRadius(new BorderRadius(10f));
//圆角-右下角
cell.setBorderBottomRightRadius(new BorderRadius(10f));
//圆角-左下角
cell.setBorderBottomLeftRadius(new BorderRadius(10f));
//圆角-右上角
cell.setBorderTopRightRadius(new BorderRadius(10f));
//圆角-左上角
cell.setBorderTopLeftRadius(new BorderRadius(10f));
//关于圆角这一部分,table中的圆角,似乎设置了并不能生效,不过可以通过将外围的table的border设置为none,内部的cell设置边框实现
例子
-
用table实现一个进度条
-
思路:外层一个一行一列的table,内部cell再套一个一行一列的table作为实际的进度,根据百分比计算内部table的宽度
-
代码:
//percent这里传的是小数 public void processBar(Document document, float width, float percent){ float processWidth = width * percent; DeviceRgb processColor = new DeviceRgb(11,11,11);//随便写个颜色吧 DeviceRgb processBgColor = new DeviceRgb(101,11,11);//随便写个颜色吧 Table table = new Table(new float[]{width}).setMargin(0).setPadding(0); Table processTable = new Table(new float[]{processWidth}).setMargin(0).setPadding(0); processTable.addCell(new Cell().setBorder(Border.NO_BORDER) .setMargin(0).setPadding(0).setBackgroundColor(processColor)); table.addCell(new Cell().setBorder(Border.NO_BORDER).setBackgroundColor(processBgColor) .setMargin(0).setPadding(0).setBorder(Border.NO_BORDER).add(processTable)); }
-
Paragraph
Paragraph para = new Paragraph("我是一个paragraph")
.setFontSize(14)//设置字体大小
.setBold()//设置文字为粗体
.setFontColor(new DeviceRgb(0,0,0))//设置字体颜色
.setTextAlignment(TextAlignment.CENTER)//文字水平居中
.setFixedLeading(14);//类似于css中的行高
有的时候会有一些需求是,同一段落的一段文字中有部分文字需要设置成别的颜色或样式样式,这时候可以Text来处理,如下:
//这种处理方式不能处理加粗的问题,如果想要加粗的文字正好在段落的中间,但是如果设置为粗体会导致整段文字都变成粗体(斜体是同理的)
para.add(new Text("我想与众不同").setFontSize("20").setFontColor(new DeviceRgb(255,255,255)));
Image
//图片分辨率问题见上面分辨率部分
Image image = new Image(ImageDataFactory.create("/home/test.jpg"));