郑永安
2023-06-19 7a6abd05683528032687c75e80e0bd2030a3e46c
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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
package com.gkhy.safePlatform.specialWork.util;
 
import com.google.zxing.WriterException;
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.*;
 
import java.io.IOException;
 
public class PdfBuilderUtils extends PdfPageEventHelper {
    /**
     * 页眉
     */
    public String header = "";
    /**
     * 页脚文本
     */
    public String fooderText = "";
    /**
     * 字体
     */
    public String fontStyle = "";
    /**
     * 字体路径
     */
    public String fontPath = "/fonts/simsun.ttf";
 
    /**
     * 文档字体大小,页脚页眉最好和文本大小一致
     */
    public int presentFontSize = 8;
 
    /**
     * 文档页面大小,最好前面传入,否则默认为A4纸张
     */
    public Rectangle pageSize = PageSize.A4;
 
    // 模板
    public PdfTemplate total;
 
    // 基础字体对象
    public BaseFont bf = null;
 
    // 利用基础字体生成的字体对象,一般用于生成中文文字
    public Font fontDetail = null;
 
    /**
     *
     * Creates a new instance of PdfReportM1HeaderFooter 无参构造方法.
     *
     */
    public PdfBuilderUtils() {
 
    }
 
    /**
     *
     * Creates a new instance of PdfReportM1HeaderFooter 构造方法.
     *
     * @param header
     *            页眉字符串
     * @param presentFontSize
     *            数据体字体大小
     * @param pageSize
     *            页面文档大小,A4,A5,A6横转翻转等Rectangle对象
     */
    public PdfBuilderUtils(String header,String fontStyle, int presentFontSize, Rectangle pageSize) {
        this.header = header;
        this.fontStyle = fontStyle;
        this.presentFontSize = presentFontSize;
        this.pageSize = pageSize;
    }
 
    public void setHeader(String header) {
        this.header = header;
    }
 
    public void setPresentFontSize(int presentFontSize) {
        this.presentFontSize = presentFontSize;
    }
 
    public void setFontPath(String fontPath){
        this.fontPath = fontPath;
    }
 
    public void setFooderText(String fooderText){
        this.fooderText = fooderText;
    }
 
    /**
     *
     * TODO 文档打开时创建模板
     *
     * @see com.itextpdf.text.pdf.PdfPageEventHelper#onOpenDocument(com.itextpdf.text.pdf.PdfWriter,
     *      com.itextpdf.text.Document)
     */
    public void onOpenDocument(PdfWriter writer, Document document) {
        total = writer.getDirectContent().createTemplate(50, 50);// 共 页 的矩形的长宽高
    }
 
    /**
     *
     * TODO 关闭每页的时候,写入页眉,写入'第几页共'这几个字。
     *
     * @see com.itextpdf.text.pdf.PdfPageEventHelper#onEndPage(com.itextpdf.text.pdf.PdfWriter,
     *      com.itextpdf.text.Document)
     */
    public void onEndPage(PdfWriter writer, Document document) {
        this.addPage(writer, document);
        this.addQrCode(writer);
    }
 
    //加分页
    public void addPage(PdfWriter writer, Document document){
 
        try {
            if (bf == null) {
                bf = BaseFont.createFont(fontPath, BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
            }
            if (fontDetail == null) {
                fontDetail = new Font(bf, presentFontSize, Font.NORMAL);// 数据体字体
            }
        } catch (DocumentException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
 
        // 1.写入页眉
        ColumnText.showTextAligned(writer.getDirectContent(),
                Element.ALIGN_LEFT, new Phrase(header, fontDetail),
                document.left(), document.top() + 20, 0);
        // 2.写入前半部分的 第 X页/共
        int pageS = writer.getPageNumber();
        String foot1 = fooderText + "      第 " + pageS + " 页/共 ";
        Phrase footer = new Phrase(foot1, fontDetail);
 
        // 3.计算前半部分的foot1的长度,后面好定位最后一部分的'Y页'这俩字的x轴坐标,字体长度也要计算进去 = len
        float len = bf.getWidthPoint(foot1, presentFontSize);
 
        // 4.拿到当前的PdfContentByte
        PdfContentByte cb = writer.getDirectContent();
 
        // 5.写入页脚1,x轴就是(右margin+左margin + right() -left()- len)/2.0F
        // 再给偏移20F适合人类视觉感受,否则肉眼看上去就太偏左了
        // ,y轴就是底边界-20,否则就贴边重叠到数据体里了就不是页脚了;注意Y轴是从下往上累加的,最上方的Top值是大于Bottom好几百开外的。
        ColumnText
                .showTextAligned(
                        cb,
                        Element.ALIGN_CENTER,
                        footer,
                        (document.rightMargin() + document.right()
                                + document.leftMargin() - document.left() - len) / 2.0F + 20F,
                        document.bottom() - 20, 0);
 
        // 6.写入页脚2的模板(就是页脚的Y页这俩字)添加到文档中,计算模板的和Y轴,X=(右边界-左边界 - 前半部分的len值)/2.0F +
        // len , y 轴和之前的保持一致,底边界-20
        cb.addTemplate(total, (document.rightMargin() + document.right()
                        + document.leftMargin() - document.left()) / 2.0F + 20F,
                document.bottom() - 20); // 调节模版显示的位置
 
    }
    /**
     * 添加二维码
     */
    public void addQrCode(PdfWriter writer){
        // 图片
        Image image;
        try {
            image = Image.getInstance(QrCodeUtil.toByte(fooderText));
            image.setAbsolutePosition(470,755);
            if(writer.getCurrentPageNumber() == 1){
                //插入图片
                PdfContentByte content = writer.getDirectContentUnder();
                content.beginText();
                content.addImage(image);
                content.endText();
            }
 
        } catch (IOException | DocumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (WriterException e) {
            throw new RuntimeException(e);
        }
 
 
    }
 
    /**
     *
     * TODO 关闭文档时,替换模板,完成整个页眉页脚组件
     *
     * @see com.itextpdf.text.pdf.PdfPageEventHelper#onCloseDocument(com.itextpdf.text.pdf.PdfWriter,
     *      com.itextpdf.text.Document)
     */
    public void onCloseDocument(PdfWriter writer, Document document) {
        // 7.最后一步了,就是关闭文档的时候,将模板替换成实际的 Y 值,至此,page x of y 制作完毕,完美兼容各种文档size。
        total.beginText();
        total.setFontAndSize(bf, presentFontSize);// 生成的模版的字体、颜色
        String foot2 = (writer.getPageNumber()) + " 页";
        total.showText(foot2);// 模版显示的内容
        total.endText();
        total.closePath();
    }
 
}