{{format('0')}} {{format('366')}} {{format('4598')}}

Itext7 API总结 [ 技术杂谈 ]

九叶的小窝 文章 正文

As Long As You Love Me.
分享

九叶

{{nature("2022-03-08 15:38:12")}}更新

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"));
评论 0
0
{{userInfo.data?.nickname}}
{{userInfo.data?.email}}
TOP 2
Minecraft | [1.12.2] 核电工艺模拟器 1.2.25 —— 汉化版

{{nature('2021-12-07 15:29:00')}} {{format('2396')}}人已阅读

TOP 3
SSM搭建Spring单元测试环境

{{nature('2021-01-31 20:01:00')}} {{format('1034')}}人已阅读

TOP 4
dispatcher-servlet.xml文件配置模板

{{nature('2020-12-11 21:17:00')}} {{format('947')}}人已阅读

TOP 5
Windows平台Nacos启动报错无法创建Bean实例

{{nature('2021-04-22 15:16:00')}} {{format('926')}}人已阅读

目录

标签云

Java Itext PDF

一言

# {{hitokoto.data.from || '来自'}} #
{{hitokoto.data.hitokoto || '内容'}}
作者:{{hitokoto.data.from_who || '作者'}}
自定义UI
配色方案

侧边栏