不廢話,上代碼。java
POM文件引用:spring
<!-- PDF操做依賴 --> <dependency> <groupId>com.itextpdf</groupId> <artifactId>root</artifactId> <version>7.1.12</version> <type>pom</type> </dependency> <dependency> <groupId>com.itextpdf</groupId> <artifactId>itext7-core</artifactId> <version>7.1.12</version> <type>pom</type> </dependency> <dependency> <groupId>com.itextpdf</groupId> <artifactId>kernel</artifactId> <version>7.1.12</version> </dependency> <dependency> <groupId>com.itextpdf</groupId> <artifactId>io</artifactId> <version>7.1.12</version> </dependency> <dependency> <groupId>com.itextpdf</groupId> <artifactId>layout</artifactId> <version>7.1.12</version> </dependency> <dependency> <groupId>com.itextpdf</groupId> <artifactId>forms</artifactId> <version>7.1.12</version> </dependency> <dependency> <groupId>com.itextpdf</groupId> <artifactId>pdfa</artifactId> <version>7.1.12</version> </dependency> <dependency> <groupId>com.itextpdf</groupId> <artifactId>sign</artifactId> <version>7.1.12</version> </dependency> <dependency> <groupId>com.itextpdf</groupId> <artifactId>barcodes</artifactId> <version>7.1.12</version> </dependency> <dependency> <groupId>com.itextpdf</groupId> <artifactId>font-asian</artifactId> <version>7.1.12</version> </dependency> <dependency> <groupId>com.itextpdf</groupId> <artifactId>hyph</artifactId> <version>7.1.12</version> </dependency> <!-- 二維碼 條形碼 生成 --> <dependency> <groupId>com.google.zxing</groupId> <artifactId>core</artifactId> <version>3.4.0</version> </dependency> <dependency> <groupId>com.google.zxing</groupId> <artifactId>javase</artifactId> <version>3.4.0</version> </dependency>
頁眉頁腳樣式VO:apache
package ; import lombok.Data; /** * 頁眉 頁腳 信息 <br/> * <br/> * <br/> * * @author Email:209308343@qq.com * @date 2020年9月2日 09:29:40 * @project * @Version */ @Data public class PageHeaderFooterVO { /** * 中間位置 文本 * 可能帶變量,好比 頁碼 總頁數 時間 等等 */ private String center; /** * 左側位置 文本 */ private String left; /** * 右側位置 文本 */ private String right; /** * 下邊距 (像素px) */ private float marginBottom; /** * 上邊距 (像素px) */ private float marginTop; /** * 是不是 頁眉, false就是頁腳 */ private boolean head; /** * 字體大小 */ private int fontSize; /** * 文本 顏色 16進制 */ private String fontColor; }
頁面設置VO:canvas
package ; import lombok.Data; /** * 頁面設置 <br/> * <br/> * <br/> * * @author Email:209308343@qq.com * @date 2020年9月2日 09:29:40 * @project * @Version */ @Data public class PageSettingVO { /** * 頁面 方向: 0 橫向, 1 縱向 */ private int pageDirection; /** * 頁面背景圖 的地址: url 或者 文件路徑 */ private String backGround; /** * 是否打印 頁面背景圖 */ private boolean printBackGround; /** * 打印類型: 套打 0, 文檔 1 */ private int printDocType; /** * 是否顯示 下載按鈕 */ private boolean isDownload; /** * 頁眉 */ private PageHeaderFooterVO pageHeader; /** * 頁腳 */ private PageHeaderFooterVO pageFooter; /** * 頁面高度 (像素 px) */ private float height; /** * 頁面寬度 (像素 px) */ private float width; /** * 上邊距 (像素 px) */ private float marginTop; /** * 下邊距 (像素 px) */ private float marginBottom; /** * 左邊距 (像素 px) */ private float marginLeft; /** * 右邊距 (像素 px) */ private float marginRight; /** * 跨頁 是否 重複打印子表頭 */ private boolean printHeadRepeatedly; /** * 跨頁 默認的行距 */ private int rowSpace; }
頁眉頁腳生成:app
package ; import cn.hutool.http.HttpUtil; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.itextpdf.io.image.ImageDataFactory; import com.itextpdf.kernel.colors.Color; import com.itextpdf.kernel.colors.ColorConstants; import com.itextpdf.kernel.colors.DeviceRgb; import com.itextpdf.kernel.events.IEventHandler; import com.itextpdf.kernel.events.PdfDocumentEvent; import com.itextpdf.kernel.font.PdfFont; import com.itextpdf.kernel.font.PdfFontFactory; import com.itextpdf.kernel.geom.PageSize; import com.itextpdf.kernel.geom.Rectangle; import com.itextpdf.kernel.pdf.PdfDocument; import com.itextpdf.kernel.pdf.PdfPage; import com.itextpdf.kernel.pdf.PdfWriter; import com.itextpdf.kernel.pdf.canvas.PdfCanvas; import com.itextpdf.layout.Canvas; import com.itextpdf.layout.Document; import com.itextpdf.layout.element.Paragraph; import com.itextpdf.layout.property.TextAlignment; import com.itextpdf.layout.property.VerticalAlignment; import lombok.Data; import org.apache.commons.lang3.StringUtils; import org.dom4j.DocumentException; import org.springframework.data.domain.Page; import java.io.IOException; import java.io.OutputStream; import java.text.SimpleDateFormat; import java.util.*; import java.util.regex.Pattern; /** * 打印模板 工具類 <br/> * <br/> * <br/> * * @author Email:209308343@qq.com * @date 2020/9/2 17:12 * @project * @Version */ public class PrintTemplteUtil { /** * 根據 打印模板和 數據 生成 pdf到 指定的輸出流裏面 * * @param templateAggVO * @param datas * @param outputStream * @return */ public static void buildPdf(final FormPrintTemplateAggVO templateAggVO , final Page<Map<String, Object>> datas, final OutputStream outputStream) throws IOException { Content content = new Content(); content.setFont(createDefualtFont()); content.setTemplateAggVO(templateAggVO); content.setNowTime(new Date()); content.setDatas(datas); content.setDateFormat(new SimpleDateFormat("yyyy-MM-dd")); content.setDateTimeFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")); content.setTimeFormat(new SimpleDateFormat("HH:mm:ss")); content.setVariables(Maps.newHashMap()); initContentVariables(content); createPdf(content, outputStream); Document document = content.getDocument(); PdfDocument pdfDocument = content.getPdfDocument(); PrintTemplateVO printTemplate = templateAggVO.getPrintTemplate(); PdfWriter pdfWriter = content.getWriter(); PageSettingVO pageSetting = printTemplate.getPageSetting(); if (pageSetting.isPrintBackGround() && StringUtils.isNotBlank(pageSetting.getBackGround())) { //若是設置了 顯示背景圖片,且有圖片 pdfDocument.addEventHandler(PdfDocumentEvent.START_PAGE, new BackGroundImage(HttpUtil.downloadBytes(pageSetting.getBackGround()))); } /* AuthService authService = SpringUtils.getBean(AuthService.class); YsWfUserEntity user = authService.getUser(); document.addAuthor(null == user ? user.getUserName() : ""); document.addCreator(null == user ? user.getUserId() : ""); */ PdfFont font = content.getFont().getFont(); Paragraph p3 = new Paragraph("而尷尬房吧發噶發梵蒂岡11111111"); p3.setFont(font); document.add(p3); Paragraph p2 = new Paragraph("你愛好啊哦哦2222222222").setMargin(0); pdfDocument.addNewPage(); p2.setFont(font); new Canvas(new PdfCanvas(pdfDocument.getLastPage()) , new Rectangle(36, 200, 108, 160)) .add(p2); List<Map<String, Object>> dataVOs = datas.getContent(); if (templateAggVO.isPreview()) { //預覽, 直接輸出預覽數據 dataVOs = Collections.singletonList(buildPreviewData(content)); } for (int i = 0; i < dataVOs.size(); i++) { fillData2Pdf(content); } new WriterPdfHeaderFooter(content).write(); document.close(); } /** * 填充變量 * * @param content */ private static void initContentVariables(Content content) { Map<String, Object> variables = content.getVariables(); variables.put(PrintTemplateVariableKeys.GLOBAL_DATE , content.getDateFormat().format(content.getNowTime())); variables.put(PrintTemplateVariableKeys.GLOBAL_DATETIME , content.getDateTimeFormat().format(content.getNowTime())); if (content.getLoginUser() != null) { variables.put(PrintTemplateVariableKeys.GLOBAL_LOGIN_USERID , content.getLoginUser().getUserId()); variables.put(PrintTemplateVariableKeys.GLOBAL_LOGIN_USERNAME , content.getLoginUser().getUserName()); variables.put(PrintTemplateVariableKeys.GLOBAL_LOGIN_USERNIKENAME , content.getLoginUser().getNickname()); variables.put(PrintTemplateVariableKeys.GLOBAL_LOGIN_USERPHONE , content.getLoginUser().getUserPhone()); } variables.put(PrintTemplateVariableKeys.GLOBAL_TIME , content.getTimeFormat().format(content.getNowTime())); } public static PdfFontAndStyle createDefualtFont() throws IOException { com.itextpdf.kernel.font.PdfFont font = PdfFontFactory.createFont("STSong-Light" , "UniGB-UCS2-H"); PdfFontAndStyle f = new PdfFontAndStyle(); f.setFont(font); f.setStyle(new FontVO()); f.getStyle().setFontSize(12); return f; } /** * 根據變量 填充 字符串 * * @param source * @param content * @return */ public static String fillVariables(String source, Content content) { if (StringUtils.isBlank(source)) { return source; } Map<String, Object> variables = content.getVariables(); ArrayList<String> strs = splitByPrintVariable(source); StringBuilder re = new StringBuilder(source.length() << 1); String s; for (int i = 0; i < strs.size(); i++) { s = strs.get(i); re.append(isPrintVariable(s) ? (variables.containsKey(s) ? variables.get(s).toString() : s) : s); } return re.toString(); } /** * 分析字符串裏 提取出 普通字符串和 打印模板公式 字符串 * * @param str * @return */ public static ArrayList<String> splitByPrintVariable(String str) { ArrayList<String> ss = Lists.newArrayList(); char[] chars = str.toCharArray(); StringBuilder txt = new StringBuilder(); StringBuilder va = new StringBuilder(); boolean in = false; char c; for (int i = 0; i < chars.length; i++) { c = chars[i]; if (in && c != '}') { va.append(c); continue; } if (c == '$' && chars[i + 1] == '{') { in = true; va.append(c); if (txt.length() > 0) { ss.add(txt.toString()); txt.delete(0, txt.length()); } continue; } if (in && c == '}') { in = false; va.append(c); if (va.length() > 0) { ss.add(va.toString()); va.delete(0, va.length()); } continue; } txt.append(c); } if (txt.length() > 0) { ss.add(txt.toString()); } if (va.length() > 0) { ss.add(va.toString()); } return ss; } /** * 是不是打印模板變量 * * @param str * @return */ public static boolean isPrintVariable(String str) { return StringUtils.isNotBlank(str) && str.startsWith("${") && str.endsWith("}"); } /** * 根據打印模板 生成 預覽測試數據 * * @param templateAggVO * @return */ private static Map<String, Object> buildPreviewData(Content content) { FormPrintTemplateAggVO templateAggVO = content.getTemplateAggVO(); FormTableInfoVO formTableInfoVO = templateAggVO.getFormTableInfoVO(); List<FormTableFiledInfoVO> fileds = formTableInfoVO.getFileds(); List<FormTableInfoVO> childs = formTableInfoVO.getChilds(); Map<String, Object> root = Maps.newLinkedHashMap(); for (FormTableFiledInfoVO filed : fileds) { root.put(filed.getName(), getDemoData(filed)); } if (CollUtil.isEmpty(childs)) { return root; } Map<String, Object> cmap; List<Map<String, Object>> lines; for (FormTableInfoVO child : childs) { childs = formTableInfoVO.getChilds(); lines = Lists.newArrayList(); root.put(child.getControlsModel(), lines); for (int i = 0; i < 5; i++) { cmap = Maps.newLinkedHashMap(); for (FormTableFiledInfoVO filed : fileds) { cmap.put(filed.getName(), getDemoData(filed)); } lines.add(cmap); } } return root; } /** * 根據表單控件 獲取示例 演示數據 * * @param filed * @return */ private static Object getDemoData(FormTableFiledInfoVO filed) { if (filed.getDefalutValue() != null) { return filed.getDefalutValue(); } final String ryzs = "張三"; final String ryls = "李四"; final String ryww = "王五"; final String ry = "[" + ryzs + "," + ryls + "]"; final String bmcw = "財務一部"; final String bmjz = "建築一部"; final String bm = "[" + bmcw + "," + bmjz + "]"; final Date now = new Date(); if (ControlType.OWNER.is(filed.getType()) || ControlType.USERSEL.is(filed.getType()) || ControlType.CREATOR.is(filed.getType())) { return ryzs; } if (ControlType.DEPTMULTI.is(filed.getType())) { return bm; } if (ControlType.USERMULTI.is(filed.getType())) { return ry; } if (ControlType.DEPARTMENT.is(filed.getType())) { return bmcw; } if (ControlType.SWITCH.is(filed.getType())) { return "是"; } if (ControlType.SELECT.is(filed.getType())) { return "選項1"; } if (ControlType.RADIO.is(filed.getType())) { return "否"; } if (ControlType.NUMBER.is(filed.getType())) { return 666; } if (ControlType.DATE.is(filed.getType()) || ControlType.EDITTIME.is(filed.getType())) { return now; } if (ControlType.CHECKBOX.is(filed.getType())) { return "選項1"; } if (ControlType.ADDRESS.is(filed.getType())) { return "四川省成都市金牛區"; } if (ControlType.POSITION.is(filed.getType())) { return "四川省成都市金牛區xxx路11號"; } return "我是文本"; } /** * TODO 填充一個 表單數據 到pdf * * @param templateAggVO 模板 * @param formData 一個單據數據 */ public static void fillData2Pdf(Content content) { FormPrintTemplateAggVO templateAggVO = content.getTemplateAggVO(); PrintTemplateVO printTemplate = templateAggVO.getPrintTemplate(); } /** * 建立一個 基本的 pdf 文件 * * @param templateAggVO * @return * @throws IOException * @throws DocumentException */ public static void createPdf(final Content content, final OutputStream outputStream) throws IOException { PrintTemplateVO printTemplate = content.getTemplateAggVO().getPrintTemplate(); PageSettingVO pageSetting = printTemplate.getPageSetting(); PdfWriter pdfWriter = new PdfWriter(outputStream); PdfDocument pdfDoc = new PdfDocument(pdfWriter); Document doc = new Document(pdfDoc, new PageSize(new Rectangle(pageSetting.getMarginLeft(), pageSetting.getMarginTop() , pageSetting.getWidth(), pageSetting.getHeight()))); content.setDocument(doc); content.setWriter(pdfWriter); content.setPdfDocument(pdfDoc); } /** * 根據 16進制的 顏色,構建一個 pdf顏色 * * @param fontColor * @return */ public static Color newPdfColorWithHex(String fontColor) { if (StringUtils.isBlank(fontColor)) { return ColorConstants.BLACK; } int[] ints = ConvertColorValue.ConvertHexToRGBInts(fontColor); return new DeviceRgb(ints[0], ints[1], ints[2]); } } /** * @Description: 爲每一頁pdf都生成背景圖片 * @author: kylin * @create: 2018-01-08 18:00 **/ class BackGroundImage implements IEventHandler { /** * 圖片的bytes */ private byte[] bytes; public BackGroundImage() { } public BackGroundImage(byte[] bytes) { this.bytes = bytes; } @Override public void handleEvent(com.itextpdf.kernel.events.Event currentEvent) { PdfDocumentEvent docEvent = (PdfDocumentEvent) currentEvent; PdfPage page = docEvent.getPage(); int pageNumber = docEvent.getDocument().getNumberOfPages(); // Background color will be applied to the first page and all even pages if (pageNumber % 2 == 1 && pageNumber != 1) { return; } PdfCanvas canvas = new PdfCanvas(page); Rectangle rect = page.getPageSize(); canvas.addImage(ImageDataFactory.create(bytes), 0, 0, false); } } /** * 上下文 */ @Data class Content { /** * 打印模板信息 */ private FormPrintTemplateAggVO templateAggVO; /** * 數據 */ private Page<Map<String, Object>> datas; /*** * PDF 寫操做 */ private PdfWriter writer; /** * 文檔 */ private Document document; /** * pdf文檔 */ private PdfDocument pdfDocument; /** * 默認字體 */ private PdfFontAndStyle font; /** * 當前日期時間 */ private Date nowTime; /** * 登陸用戶 */ private YsWfUserEntity loginUser; /** * 默認 日期格式器 */ private SimpleDateFormat dateFormat; /** * 默認 日期時間 格式器 */ private SimpleDateFormat dateTimeFormat; /** * 默認 時間 格式器 */ private SimpleDateFormat timeFormat; /** * 變量 * * @see PrintTemplateVariableKeys */ private Map<String, Object> variables; } /** * 頁眉 頁腳 輸出類 */ @Data class WriterPdfHeaderFooter { private PdfFontAndStyle font; private Content content; /** * 默認 頁眉頁腳 行高 */ private float lineHeight = 50f; /** * 默認 頁眉頁腳 3個點位 一個點位 寬度 */ private float sideWidth = 100f; /** * 默認 元素 距離間隔 */ private float marginLeft = 20f; /** * 頁眉頁腳 建立類 * * @param content * @throws IOException * @throws DocumentException */ public WriterPdfHeaderFooter(Content content) throws IOException { this.content = content; this.font = content.getFont(); } public WriterPdfHeaderFooter(PdfFontAndStyle font, Content content) { this.font = font; this.content = content; } /** * 所有完成後,調用此方法 填充 頁眉頁腳變量 中好比 總頁數這種類型的 */ public void write() { PrintTemplateVO printTemplate = content.getTemplateAggVO().getPrintTemplate(); PageSettingVO pageSetting = printTemplate.getPageSetting(); PageHeaderFooterVO pageHeader = pageSetting.getPageHeader(); PageHeaderFooterVO pageFooter = pageSetting.getPageFooter(); PdfDocument pdfDocument = content.getPdfDocument(); //總頁數的變量 final int pageCount = pdfDocument.getNumberOfPages(); content.getVariables().put(PrintTemplateVariableKeys.GLOBAL_PAGECOUNT , pageCount); Paragraph text; float y; int fontSize; Color color; for (int i = 1; i <= pageCount; i++) { //當前頁的變量 content.getVariables().put(PrintTemplateVariableKeys.GLOBAL_PAGENOW , i); //頁眉 y = pageSetting.getHeight() - pageSetting.getMarginTop(); fontSize = V.getGtZero(pageHeader.getFontSize(), this.font.getStyle().getFontSize()); color = PrintTemplteUtil.newPdfColorWithHex(pageHeader.getFontColor()); //左側 text = new Paragraph(PrintTemplteUtil.fillVariables(pageHeader.getLeft(), content)); text.setFont(this.font.getFont()); text.setFontSize(fontSize); text.setFontColor(color); content.getDocument().showTextAligned(text, pageSetting.getMarginLeft() , y, i, TextAlignment.LEFT, VerticalAlignment.MIDDLE, 0); //中間 text = new Paragraph(PrintTemplteUtil.fillVariables(pageHeader.getCenter(), content)); text.setFont(this.font.getFont()); text.setFontSize(fontSize); text.setFontColor(color); content.getDocument().showTextAligned(text , (pageSetting.getWidth() - pageSetting.getMarginLeft() - pageSetting.getMarginRight()) / 2 , y, i, TextAlignment.CENTER, VerticalAlignment.MIDDLE, 0); //右側 text = new Paragraph(PrintTemplteUtil.fillVariables(pageHeader.getRight(), content)); text.setFont(this.font.getFont()); text.setFontSize(fontSize); text.setFontColor(color); content.getDocument().showTextAligned(text , pageSetting.getWidth() + pageSetting.getMarginLeft() - pageSetting.getMarginRight() , y, i, TextAlignment.RIGHT, VerticalAlignment.MIDDLE, 0); //頁腳 y = pageSetting.getMarginBottom() + (2 * this.font.getStyle().getFontSize()); fontSize = V.getGtZero(pageFooter.getFontSize(), this.font.getStyle().getFontSize()); color = PrintTemplteUtil.newPdfColorWithHex(pageFooter.getFontColor()); //左側 text = new Paragraph(PrintTemplteUtil.fillVariables(pageFooter.getLeft(), content)); text.setFont(this.font.getFont()); text.setFontSize(fontSize); text.setFontColor(color); content.getDocument().showTextAligned(text, pageSetting.getMarginLeft() , y, i, TextAlignment.LEFT, VerticalAlignment.MIDDLE, 0); //中間 text = new Paragraph(PrintTemplteUtil.fillVariables(pageFooter.getCenter(), content)); text.setFont(this.font.getFont()); text.setFontSize(fontSize); text.setFontColor(color); content.getDocument().showTextAligned(text , (pageSetting.getWidth() - pageSetting.getMarginLeft() - pageSetting.getMarginRight()) / 2 , y, i, TextAlignment.CENTER, VerticalAlignment.MIDDLE, 0); //右側 text = new Paragraph(PrintTemplteUtil.fillVariables(pageFooter.getRight(), content)); text.setFont(this.font.getFont()); text.setFontSize(fontSize); text.setFontColor(color); content.getDocument().showTextAligned(text , pageSetting.getWidth() + pageSetting.getMarginLeft() - pageSetting.getMarginRight() , y, i, TextAlignment.RIGHT, VerticalAlignment.MIDDLE, 0); } } } /** * pdf 字體樣式封裝 */ @Data class PdfFontAndStyle { private PdfFont font; private FontVO style; } /** * RGB、十六進制轉換 */ class ConvertColorValue { private static String s = "0123456789ABCDEF"; /** * RGB轉換成十六進制 * * @param r * @param g * @param b * @return */ public static String ConvertRGBToHex(int r, int g, int b) { String hex = ""; if (r >= 0 && r < 256 && g >= 0 && g < 256 && b >= 0 && b < 256) { int x, y, z; x = r % 16; r = (r - x) / 16; y = g % 16; g = (g - y) / 16; z = b % 16; b = (b - z) / 16; hex = "#" + s.substring(r, r + 1) + s.substring(x, x + 1) + s.substring(g, g + 1) + s.substring(y, y + 1) + s.substring(b, b + 1) + s.substring(z, z + 1); } return hex; } /** * 十六進制轉換成RGB * * @param hex * @return */ public static String ConvertHexToRGB(String hex) { int[] ints = ConvertHexToRGBInts(hex); return ints[0] + "," + ints[1] + "," + ints[2]; } /** * 十六進制轉換成RGB * * @param hex * @return */ public static int[] ConvertHexToRGBInts(String hex) { String regex = "^[0-9A-F]{3}|[0-9A-F]{6}$"; hex = hex.toUpperCase(); if (hex.substring(0, 1).equals("#")) { hex = hex.substring(1); } int[] ints = new int[3]; if (Pattern.compile(regex).matcher(hex).matches()) { String a, c, d; for (int i = 0; i < 3; i++) { a = hex.length() == 6 ? hex.substring(i * 2, i * 2 + 2) : hex.substring(i, i + 1) + hex.substring(i, i + 1); c = a.substring(0, 1); d = a.substring(1, 2); ints[i] = s.indexOf(c) * 16 + s.indexOf(d); } } return ints; } }
測試類:dom
FormPrintTemplateAggVO templateAggVO = new FormPrintTemplateAggVO(); templateAggVO.setAppId("234234"); templateAggVO.setFromId("12323123formid"); Page<Map<String, Object>> data = new PageImpl<>(Lists.newArrayList()); List<Map<String, Object>> ds = data.getContent(); templateAggVO.setPreview(true); FormTableInfoVO tb = new FormTableInfoVO(); templateAggVO.setFormTableInfoVO(tb); PrintTemplateVO printTemplateVO = new PrintTemplateVO(); templateAggVO.setPrintTemplate(printTemplateVO); tb.setFileds(Lists.newArrayList()); tb.setChilds(Lists.newArrayList()); FormTableFiledInfoVO f = new FormTableFiledInfoVO(); f.setDefalutValue("你好"); f.setType(ControlType.INPUT.type); tb.getFileds().add(f); f = new FormTableFiledInfoVO(); f.setType(ControlType.INPUT.type); tb.getFileds().add(f); f = new FormTableFiledInfoVO(); f.setType(ControlType.POSITION.type); tb.getFileds().add(f); f = new FormTableFiledInfoVO(); f.setType(ControlType.DATE.type); tb.getFileds().add(f); f = new FormTableFiledInfoVO(); f.setType(ControlType.NUMBER.type); tb.getFileds().add(f); f = new FormTableFiledInfoVO(); f.setType(ControlType.USERMULTI.type); tb.getFileds().add(f); //頁面設置 PageSettingVO ps = new PageSettingVO(); printTemplateVO.setPageSetting(ps); ps.setBackGround("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1599059739369&di=7ac5af471c5c6444904160b20ac2c01f&imgtype=0&src=http%3A%2F%2Fattach.bbs.miui.com%2Fforum%2F201306%2F21%2F220620bu3aduoxutyuauda.jpg"); ps.setPrintBackGround(false); ps.setHeight(PageSize.A4.getHeight()); ps.setWidth(PageSize.A4.getWidth()); ps.setMarginLeft(10f); ps.setMarginBottom(10f); ps.setMarginRight(10f); ps.setMarginTop(10f); //頁眉頁腳 ps.setPageFooter(new PageHeaderFooterVO()); ps.getPageFooter().setCenter("打印時間:${[時間]}"); ps.getPageFooter().setMarginBottom(20); ps.getPageFooter().setLeft("打印日期時間:${[日期]} ${[時間]}"); ps.getPageFooter().setRight( "這是第${[頁碼]}頁/共${[頁數]}頁" //"日時:${[日期]} ${[時間]} 第${[頁碼]}頁/共${[頁數]}頁" ); ps.getPageFooter().setFontSize(9); ps.setPageHeader(new PageHeaderFooterVO()); ps.getPageHeader().setCenter("當前時間:${[時間]}"); ps.getPageHeader().setMarginTop(20); ps.getPageHeader().setRight("今天日期:${[日期]}"); ps.getPageHeader().setLeft( "第${[頁碼]}頁/共${[頁數]}頁" //"日時:${[日期]} ${[時間]} 第${[頁碼]}頁/共${[頁數]}頁" ); ps.getPageHeader().setHead(true); ps.getPageHeader().setFontSize(16); ps.getPageHeader().setFontColor("#32CD32"); PrintTemplteUtil.buildPdf(templateAggVO, data , new FileOutputStream("G:\\360downloads\\1.pdf"));