当前位置:   article > 正文

使用PDFBox封装一个简单易用的工具类快速生成pdf文件_pdfbox 生成固定模板

pdfbox 生成固定模板

一、PDFbox说明

1、坐标

文档左下角为坐标原点,x轴向右从0增加,y轴向上增加

2、线

以起始位置至终点一条线,线宽以垂直于起始至终止连线方向发散,例如线宽20,起始位置(0,10),终止位置(500,10)则线实际所占位置为(0,0),(0,20),(500,0),(500,20)所围成的长方形区域

3、图

图位置以左下角为原点向右上方发散

4、字

字的位置以左下角为原点向右上方发散

        // 横线
        contentStream.moveTo(0, 10);
        contentStream.lineTo(540, 10);
        contentStream.stroke();
 
        // 竖线
        contentStream.moveTo(10, 0);
        contentStream.lineTo(10, 540);
        contentStream.stroke();
 
        // 斜线
        contentStream.moveTo(0, 0);
        contentStream.lineTo(540, 540);
        contentStream.stroke();
 
        // 图片
        final byte[] imageByte = IOUtils.toByteArray(Objects.requireNonNull(DrawTableUtils.class.getClassLoader().getResourceAsStream("yellow.png")));
        final PDImageXObject image = PDImageXObject.createFromByteArray(document, imageByte, "yellow.png");
        contentStream.drawImage(image, 20, 0, 50, 50);
        // 文字
        contentStream.beginText();
        contentStream.setFont(PDType1Font.HELVETICA_BOLD, 10);
        contentStream.newLineAtOffset(0, 10);
        String text = "This is the sample document and we are adding content to it.";
        contentStream.showText(text);
        contentStream.endText();
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

5、字体加载

1、ttf类型字体加载

       InputStream inFont = DrawTableUtils.class.getClassLoader().getResourceAsStream(fontName);
        PDType0Font normalFont = PDType0Font.load(document, inFont);
        PDType0Font boldFont = null;
  • 1
  • 2
  • 3

2.otf类型字体加载

        InputStream normalStream = DrawTableUtils.class.getClassLoader().getResourceAsStream(fontName);
        assert normalStream != null;
        OpenTypeFont normalOtfFont = new OTFParser(false, true).parse(normalStream);
        PDType0Font normalFont = PDType0Font.load(document, normalOtfFont, false);
  • 1
  • 2
  • 3
  • 4

6、jfreechart图表转字节数组

JFreeChart chart = new JFreeChart(title, xyplot);
// 图例字体清晰
chart.setTextAntiAlias(true);
chart.setBackgroundPaint(Color.WHITE);
TextTitle textTitle = chart.getTitle();
textTitle.setFont(new Font("黑体", Font.PLAIN, 20));
BufferedImage bufferedImage = chart.createBufferedImage(600, 300);
byte[] bytes = ChartUtilities.encodeAsPNG(bufferedImage);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

7、依赖

		<dependency>
			<groupId>org.apache.pdfbox</groupId>
			<artifactId>pdfbox</artifactId>
			<version>2.0.28</version>
		</dependency>
  • 1
  • 2
  • 3
  • 4
  • 5

二、PDFbox样式

1、文字颜色

Color color = new Color(255,0,0);
contentStream.setNonStrokingColor(color);
  • 1
  • 2

2、线颜色

Color color = new Color(255, 0, 0);
contentStream.setStrokingColor(color);
  • 1
  • 2

3、线样式

 float[] a={
   3,5};
        contentStream.setLineDashPattern(a, 0);
        contentStream.moveTo(0, 20);
        contentStream.lineTo(540, 20);
        contentStream.stroke();
 
        contentStream.setLineDashPattern(a, 20);
        contentStream.moveTo(0, 50);
        contentStream.lineTo(540, 50);
        contentStream.stroke();
 
        float[] b={
   3};
        contentStream.setLineDashPattern(b, 20);
        contentStream.moveTo(0, 80);
        contentStream.lineTo(540, 80);
        contentStream.stroke();
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

contentStream.setLineDashPattern(a, 0);

第一个参数 a={3,5} 3表明虚线宽度为3,5表明虚线间隔为5 。当a={3}时表明虚线宽度为3,间隔为3

第二个参数0表明虚线偏移量

三、工具类

边框样式

public enum BorderStyle {
   
 
    SOLID(new float[]{
   }, 0),
    DOTTED(new float[]{
   1}, 1),
    DASHED(new float[]{
   5,2}, 1);
 
    private final float[] pattern;
    private final int phase;
 
    BorderStyle(float[] pattern, int phase) {
   
        this.pattern = pattern;
        this.phase = phase;
    }
 
    public float[] getPattern() {
   
        return pattern;
    }
 
    public int getPhase() {
   
        return phase;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

对齐样式

public enum HorizontalAlignment {
   
 
    LEFT, CENTER, RIGHT
 
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

 
@Data
public class PdfTable {
   
    /**
     * 行
     */
    private List<PdfRow> rows;
    /**
     * 字体
     */
    private String font;
    public void addRow(PdfRow row){
   
        rows.add(row);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

@Data
@Builder
public class PdfRow {
   
    /**
     * 列
     */
    private List<PdfColumn> pdfColumns;
    /**
     * 行高
     */
    private float height;
    /**
     * 边框样式,仅下边框生效
     */
    private BorderStyle borderStyle;
    /**
     * 边框颜色
     */
    @Builder.Default
    private Color boderColor=Color.BLACK;
    /**
     * 下边框是否生效
     */
    private boolean downBorder;
 
    public void addColumn(PdfColumn pdfColumn){
   
        pdfColumns.add(pdfColumn);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

@Data
@Builder
public class PdfColumn {
   
    /**
     * 背景颜色
     */
    @Builder.Default
    private Color backGround = Color.WHITE;
    /**
     * 边框颜色
     */
    @Builder.Default
    private Color borderColor = Color.BLACK;
    /**
     * 文字颜色
     */
    @Builder.Default
    private Color textColor= Color.BLACK;
    /**
     * 加粗
     */
    @Builder.Default
    private boolean block=false;
    /**
     * 文字大小
     */
    @Builder.Default
    private float fontSize=10F;
    /**
     * 偏移
     */
    @Builder.Default
    private float offset=0F;
    /**
     * 文字位置
     */
    @Builder.Default
    private HorizontalAlignment align =HorizontalAlignment.CENTER;
    /**
     * 自动宽度
     */
    @Builder.Default
    private boolean autoWidth=false;
    /**
    * 自动换行
    */
    @Builder.Default
    private boolean autoWidth=false;
    /**
     * 左边框
     */
    private boolean leftBorder;
    /**
     * 右边框
     */
    private boolean rightBorder;
    /**
     * 名称
     */
    private String name;
    /**
     * 宽度,仅在自动宽度未生效时启用
     */
    private float width;
    /**
     * 图片,图片生效时其他属性均不生效
     */
    private PdfColumnImage columnImage;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70

图片列

@Data
@Builder
public class PdfColumnImage {
   
    /**
     * 图片名称/路径
     */
    private String image;
    /**
     * x轴位置
     */
    private float x;
    /**
     * y轴位置
     */
    private float y;
    /**
     * 图片宽度
     */
    private float width;
    /**
     * 图片高度
     */
    private float height;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

pdf工具类

public class DrawTableUtils {
   
 
    /**
     * 页边距
     */
    private static final float PADDING = 30;
    /**
     * 下表格线偏移
     */
    private static final float DOWN_LINE_PADDING = 0.5f;
    /**
     * 边框宽度
     */
    private static final float BORDER_WIDTH = 1;
    /**
     * 生成PDF
     *
     * @param table pdf数据
     * @throws IOException
     */
    public static void createDocument(PdfTable table) throws IOException {
   
        // 初始化文档
        PDDocument document = new PDDocument();
        final PDPage page = new PDPage(PDRectangle.A4);
        document.addPage(page);
        // 字体
        String fontName = table.getFont();
        InputStream inFont = org.bmc.DrawTableUtils.class.getClassLoader().getResourceAsStream(fontName);
        PDType0Font font = PDType0Font.load(document, inFont);
        // 页
        int pageNum = 1;
        // 初始化文档位置
        org.bmc.DrawTableUtils.Position position = new org.bmc.DrawTableUtils.Position(PADDING, page.getMediaBox().getHeight() - PADDING, 0);
        PDPageContentStream contentStream = new PDPageContentStream(document, page);
 
        for (PdfRow row : table.getRows()) {
   
            // 分页
            if (position.startY <= PADDING * 2) {
   
                pageNum++;
                PDPage pdPage = new PDPage(PDRectangle.A4);
                document.addPage(pdPage);
                position.startY = page.getMediaBox().getHeight() - PADDING;
                contentStream.close();
                contentStream = new PDPageContentStream(document, pdPage);
            }
 
            drawLine(row, document, contentStream, position, font);
 
            if (row.isDownBorder()) {
   
                drawDrownBorder(contentStream, page, row, position);
            }
 
 
        }
        contentStream.close();
        // 页脚
        drawPageFoot(document, pageNum, font);
        // 保存文档
        document.save("D:/mypdf.pdf");
        document.close();
    }
 
 
    /**
     * 生成表格下框,以行为单位
     *
     * @param contentStream 流
     * @param page          页
     * @param row           行
     * @param position      位置
     * @throws IOException
     */
    private static void drawDrownBorder(PDPageContentStream contentStream, PDPage page, PdfRow row, org.bmc.DrawTableUtils.Position position) throws IOException {
   
        contentStream.
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/623564
推荐阅读
相关标签
  

闽ICP备14008679号