ITEXT7 生成PDF ,添加背景图,表格居中,以及分页表格断开的处理,图片并排, 页眉处理
转载请注明文章出处,谢谢!
公司要求给客户生成PDF报告,本来是使用itext5,html转为pdf, 但是最后一张需要添加背景图,一直没有找到判断是否是最后一张或者说给整个pdf最后添加一页空白页的方法, 最后只能使用itext7,手动写PDF报告,网上也有很多教程,但是有些东西还是找不到,整了几天,搞出来满足需求的,仅此记录一下
效果图
一些图片以及字体位置
pom
<!--itext7全家桶--> <dependency> <groupId>com.itextpdf</groupId> <artifactId>itext7-core</artifactId> <version>7.1.15</version> <type>pom</type> </dependency>
PDFTestController 测试类
package com.example.note.pdf; import com.example.note.pdf.domain.Constants; import com.example.note.pdf.domain.PdfTestInfo; import com.example.note.pdf.domain.entity.PDFTest; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.util.Arrays; import java.util.List; /** * @author wqqing * @date 2022/8/30 16:17 */ @RestController @RequestMapping("pdf-test") public class PDFTestController { @GetMapping("/") public void test() throws Exception { PdfTestInfo info = new PdfTestInfo(); //字体路径 String path = this.getClass().getClassLoader().getResource("").getPath(); info.setStFondPath(path + Constants.SONGTI_FONTS_PATH); info.setWryhFondPath(path + Constants.YAHEI_FONTS_PATH); List<PDFTest> tableDatas = Arrays.asList( new PDFTest(1l, "english", "yingwen", "asgdag"), new PDFTest(2l, "中文测试", "中文测试", "中文呀") ); info.setTableDatas(tableDatas); List<String> images = Arrays.asList( ImageHelpers.imageToBase64(path+"/image/1.png"), ImageHelpers.imageToBase64(path+"/image/2.png"), ImageHelpers.imageToBase64(path+"/image/3.png"), ImageHelpers.imageToBase64(path+"/image/4.png") ); info.setImages(images); info.setImage1(path+"/image/image1.png"); info.setImage2(path+"/image/image2.jpg"); GeneratePDFReport.generatePdf(info); } }
实体类
PDFTest模拟数据库查询出来的数据信息
package com.example.note.pdf.domain.entity; import com.baomidou.mybatisplus.annotation.TableId; import com.example.note.pdf.domain.IgnoreFiled; import com.example.note.pdf.domain.SeqNo; import lombok.Data; /** * @author wqqing * @date 2022/8/30 16:06 */ @Data public class PDFTest { @IgnoreFiled @TableId private Long id; @SeqNo(1)//统一处理的时候 获取表格数据 按照数值大小顺序获取属性 private String name; @SeqNo(2) private String desc; @SeqNo(3) private String info; public PDFTest(){ } public PDFTest(Long id, String name, String desc, String info) { this.id = id; this.name = name; this.desc = desc; this.info = info; } }
PdfTestInfo pdf数据信息
package com.example.note.pdf.domain; import com.example.note.pdf.domain.entity.PDFTest; import lombok.Data; import java.util.List; /** * @author wqqing * @date 2022/8/30 16:18 */ @Data public class PdfTestInfo { private List<PDFTest> tableDatas; private List<String> images; private String stFondPath; private String wryhFondPath; private String image1; private String image2; }
自定义注解,方便查询类的属性值
package com.example.note.pdf.domain; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * @author wqqing * @date 2022/8/26 13:10 */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) public @interface IgnoreFiled { }
package com.example.note.pdf.domain; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * @author wqqing * @date 2022/8/26 13:06 */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) public @interface SeqNo { int value(); }
Constants 常量类
package com.example.note.pdf.domain; /** * @author wqqing * @date 2022/8/16 11:14 */ public class Constants { /**宋体**/ public static String SONGTI_FONTS_PATH = "font/simsun.ttc,0"; /**雅黑**/ public static String YAHEI_FONTS_PATH = "/font/msyh.ttc,0"; }
PDFStyleContants pdf样式常量信息
package com.example.note.pdf.domain; import com.itextpdf.kernel.colors.Color; import com.itextpdf.kernel.colors.DeviceRgb; /** * @author wqqing * @date 2022/8/25 16:43 */ public class PDFStyleContants { /**右边距**/ public static float MARGIN_RIGHT = 40; /**左边距**/ public static float MARGIN_LEFT = 40; /**上边距**/ public static float MARGIN_TOP = 40; /**下边距**/ public static float MARGIN_BOTTOM = 40; /**内容中文字体大小**/ public static float CONTENT_FONT_SIZE = 16; /**标题中文字体大小**/ public static float TITLE_FONT_SIZE = 18; /**红色**/ public static Color RED = Color.convertRgbToCmyk(new DeviceRgb(java.awt.Color.RED)); /**深蓝色**/ public static Color MAX_BLUE = Color.convertRgbToCmyk(new DeviceRgb(17, 30,65)); /**白色**/ public static Color WHITE = Color.convertRgbToCmyk(new DeviceRgb(java.awt.Color.WHITE)); /**黑色**/ public static Color BLACK = Color.convertRgbToCmyk(new DeviceRgb(java.awt.Color.BLACK)); /**灰色**/ public static Color GRAY = Color.convertRgbToCmyk(new DeviceRgb(216, 216,216)); /**页眉字体大小**/ public static float HEADER_FONT_SIZE = 12; }
HeaderFooterHanlder 页眉处理
package com.example.note.pdf; import com.example.note.pdf.domain.PDFStyleContants; import com.itextpdf.kernel.events.Event; import com.itextpdf.kernel.events.IEventHandler; import com.itextpdf.kernel.events.PdfDocumentEvent; import com.itextpdf.kernel.font.PdfFont; import com.itextpdf.kernel.geom.Rectangle; import com.itextpdf.kernel.pdf.PdfDocument; import com.itextpdf.kernel.pdf.PdfPage; import com.itextpdf.kernel.pdf.canvas.PdfCanvas; import com.itextpdf.layout.Document; import com.itextpdf.layout.borders.Border; import com.itextpdf.layout.element.Paragraph; import com.itextpdf.layout.element.Tab; import com.itextpdf.layout.element.TabStop; import com.itextpdf.layout.element.Table; import com.itextpdf.layout.property.HorizontalAlignment; import com.itextpdf.layout.property.TabAlignment; import com.itextpdf.layout.property.TextAlignment; import com.itextpdf.layout.property.VerticalAlignment; /** * @author wqqing * @date 2022/8/29 10:31 */ public class HeaderFooterHanlder implements IEventHandler { /**字体**/ private final PdfFont pdfFont; /**左侧表头**/ private final String leftHeader; /**右侧表头**/ private final String rightHeader; public HeaderFooterHanlder(PdfFont pdfFont, String leftHeader, String rightHeader){ this.pdfFont = pdfFont; this.leftHeader = leftHeader; this.rightHeader = rightHeader; } @Override public void handleEvent(Event event) { PdfDocumentEvent pdfDocumentEvent = (PdfDocumentEvent) event; PdfPage page = pdfDocumentEvent.getPage(); PdfDocument pdfDocument = pdfDocumentEvent.getDocument(); Document doc = new Document(pdfDocument); int pageNums = pdfDocument.getNumberOfPages(); int pageNumber = pdfDocument.getPageNumber(page); try{ //首页,最后一页不添加页眉 if (pageNumber > 1 && pageNumber != pageNums) { Rectangle pageSize = pdfDocument.getDefaultPageSize(); float pdfWidth = pageSize.getWidth(); float pdfHeight = pageSize.getHeight(); PdfCanvas pdfCanvas = new PdfCanvas(page.getLastContentStream(), page.getResources(), pdfDocument); pdfCanvas.setLineWidth(1.5f).setStrokeColor(PDFStyleContants.BLACK); float tableWidth = pdfWidth - doc.getRightMargin() - doc.getLeftMargin(); /**页眉**/ float x0 = doc.getRightMargin(), y0 = pdfHeight - doc.getTopMargin(); pdfCanvas.moveTo(x0, y0).lineTo(pdfWidth - doc.getRightMargin(), y0).stroke(); Table table = TableHelper.table(2, 30, true, tableWidth, HorizontalAlignment.CENTER, null, true, PDFStyleContants.MARGIN_LEFT, y0, tableWidth); table.addCell(TableHelper.cell(1, 1, PDFHelpers.paragraph(leftHeader, false).setFont(pdfFont).setVerticalAlignment(VerticalAlignment.BOTTOM), false, Border.NO_BORDER, TextAlignment.LEFT, null, VerticalAlignment.BOTTOM)); Paragraph date = new Paragraph(); date.setVerticalAlignment(VerticalAlignment.BOTTOM); date.add(new Tab()).addTabStops(new TabStop(1000, TabAlignment.RIGHT)); date.add(rightHeader).setFont(pdfFont); table.addCell(TableHelper.cell(1, 1, date, false, Border.NO_BORDER, null, null, VerticalAlignment.BOTTOM)); table.setFixedPosition(doc.getLeftMargin(), pdfHeight - doc.getTopMargin(), tableWidth); doc.add(table); } }catch (Exception e){ e.printStackTrace(); } } }
ImageHelpers 处理图片数据,可以处理base64以及URL两种格式,实现图片居中,图片并排显示
package com.example.note.pdf; import com.example.note.pdf.domain.PDFStyleContants; import com.itextpdf.io.image.ImageDataFactory; import com.itextpdf.kernel.geom.PageSize; import com.itextpdf.kernel.pdf.PdfDocument; import com.itextpdf.layout.element.Image; import sun.misc.BASE64Decoder; import java.io.*; import java.util.Base64; /** * @author wqqing * @date 2022/8/25 16:50 */ public class ImageHelpers { /** * 图片铺满整个页面 * @param pdfDocument * @return * @throws Exception */ public static Image generateBackgroudImage(String imagePath, PdfDocument pdfDocument) throws Exception{ Image image = new Image(ImageDataFactory.create(base64TOByte(imagePath))); PageSize pageSize = pdfDocument.getDefaultPageSize(); image.scaleToFit(pageSize.getWidth(), pageSize.getHeight()); image.setMargins(0- PDFStyleContants.MARGIN_TOP, 0- PDFStyleContants.MARGIN_RIGHT, 0- PDFStyleContants.MARGIN_BOTTOM, 0- PDFStyleContants.MARGIN_LEFT); return image; } /** * 图片转为base64编码 * @param imagePath * @return * @throws Exception */ public static byte[] base64TOByte(String imagePath) throws Exception{ BASE64Decoder base64Decoder = new BASE64Decoder(); return base64Decoder.decodeBuffer(imageToBase64(imagePath)); } /** * 图片自适应 * @param base64 * @param autoScale * @return * @throws Exception */ public static Image generateImage(String base64, boolean autoScale) throws Exception{ BASE64Decoder base64Decoder = new BASE64Decoder(); Image image = new Image(ImageDataFactory.create(base64Decoder.decodeBuffer(base64))); image.setAutoScale(autoScale); return image; } /** * 图片居中显示 目前用margin控制 * @param base64 * @param pageSize * @return */ public static Image generateImage(String base64, PageSize pageSize) throws Exception{ BASE64Decoder base64Decoder = new BASE64Decoder(); Image image = new Image(ImageDataFactory.create(base64Decoder.decodeBuffer(base64))); float pageEmptyWidth = pageSize.getWidth()- PDFStyleContants.MARGIN_LEFT- PDFStyleContants.MARGIN_RIGHT; float imageWidth = image.getImageWidth(); if (imageWidth > pageEmptyWidth){ image.setWidth(pageEmptyWidth); }else{ float margin = (pageEmptyWidth-imageWidth)/2; image.setMarginRight(margin).setMarginLeft(margin); } return image; } /** * @Description: 将图片转换成base64编码的字符串 * @param @param imageSrc 文件路径 * @param @return * @return String * @throws IOException */ public static String imageToBase64(String imageSrc) throws IOException{ //判断文件是否存在 File file=new File(imageSrc); if(!file.exists()){ throw new FileNotFoundException("文件不存在!"); } StringBuilder pictureBuffer = new StringBuilder(); FileInputStream input=new FileInputStream(file); ByteArrayOutputStream out = new ByteArrayOutputStream(); byte[] temp = new byte[1024]; for(int len = input.read(temp); len != -1;len = input.read(temp)){ out.write(temp, 0, len); } pictureBuffer.append(Base64.getEncoder().encodeToString(out.toByteArray())); input.close(); return pictureBuffer.toString(); } }
TableHelper 表格相关数据处理,表格居中,默认值
package com.example.note.pdf; import com.example.note.pdf.domain.IgnoreFiled; import com.example.note.pdf.domain.PDFStyleContants; import com.example.note.pdf.domain.SeqNo; import com.itextpdf.kernel.colors.Color; import com.itextpdf.layout.borders.Border; import com.itextpdf.layout.element.Cell; import com.itextpdf.layout.element.Image; import com.itextpdf.layout.element.Paragraph; import com.itextpdf.layout.element.Table; import com.itextpdf.layout.property.HorizontalAlignment; import com.itextpdf.layout.property.TextAlignment; import com.itextpdf.layout.property.UnitValue; import com.itextpdf.layout.property.VerticalAlignment; import org.apache.commons.collections4.CollectionUtils; import java.lang.reflect.Field; import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; /** * @author wqqing * @date 2022/8/25 20:07 */ public class TableHelper { /** * 获取表头 * @param table * @param rowspan * @param colspan * @param headers */ public static void header(Table table, int rowspan, int colspan, List<String> headers){ for(String head : headers){ table.addHeaderCell(headCell(rowspan, colspan, head)); } } /** * 内容处理 * @param table * @param rowspan * @param colspan * @param texts */ public static void content(Table table, int rowspan, int colspan, List<Object> texts){ for(Object text : texts){ table.addCell(cell(rowspan, colspan, text,false)); } } /** * 处理表格头部数据 * @param rowspan * @param colspan * @param text * @return */ public static Cell headCell(int rowspan, int colspan, String text){ return headCell(rowspan, colspan, 0, 0, text); } /** * 单元格 * @param rowspan 行合并数 * @param colspan 列合并数 * @param height 高度 * @param width 宽度 * @param text 内容 * @return */ public static Cell headCell(int rowspan, int colspan, float height, float width, String text){ return cell(rowspan, colspan, PDFHelpers.paragraph(text, true), height, width, 40, true, null, PDFStyleContants.GRAY); } /** * 单元格 * @param rowspan 行合并数 * @param colspan 列合并数 * @param text 内容 * @param bold 是否加粗 * @return */ public static Cell cell(int rowspan, int colspan, Object text, boolean bold){ return cell(rowspan, colspan, PDFHelpers.paragraph(text, bold)); } /** * 单元格 * @param rowspan 行合并数 * @param colspan 列合并数 * @param text 内容 * @return */ public static Cell cell(int rowspan, int colspan, Paragraph text){ return cell(rowspan, colspan, text, 0 ,0, 0); } /** * 单元格 * @param rowspan 行合并数 * @param colspan 列合并数 * @param text 内容 * @param height 高度 * @param width 宽度 * @param minHeight 最小高度 * @return */ public static Cell cell(int rowspan, int colspan, Paragraph text, float height, float width, float minHeight){ return cell(rowspan, colspan, text, height, width, minHeight, true, null, null); } /** * 单元格 * @param rowspan 行合并数 * @param colspan 列合并数 * @param text 内容 * @param height 高度 * @param width 宽度 * @param minHeight 最小高度 * @param isDefaultBorder 是否默认边康 * @param border 自定义边框 * @return */ public static Cell cell(int rowspan, int colspan, Paragraph text, float height, float width, float minHeight, boolean isDefaultBorder, Border border){ return cell(rowspan, colspan, text, height, width, minHeight, isDefaultBorder, border, null); } /** * 单元格处理 * @param rowspan 行合并数 * @param colspan 列合并数 * @param text 内容 * @param height 高度 * @param width 宽度 * @param minHeight 最小高度 * @param isDefaultBorder 是否默认边框 * @param border 自定义边框 * @param background 背景 * @return */ public static Cell cell(int rowspan, int colspan, Paragraph text, float height, float width, float minHeight, boolean isDefaultBorder, Border border, Color background){ return cell(rowspan, colspan, text, height, width, minHeight, isDefaultBorder, border, background, null, null, null); } /** * 单元格处理 * @param rowspan 行合并数 * @param colspan 列合并数 * @param text 内容 * @param isDefaultBorder 是否默认边框 * @param border 自定义边框 * @param textAlignment 文字布局 * @param horizontalAlignment 水平方式布局 * @param verticalAlignment 垂直方向布局 * @return */ public static Cell cell(int rowspan, int colspan, Paragraph text, boolean isDefaultBorder, Border border, TextAlignment textAlignment, HorizontalAlignment horizontalAlignment, VerticalAlignment verticalAlignment) { return cell(rowspan, colspan, text, 0, 0, 0, isDefaultBorder, border, null, textAlignment, horizontalAlignment, verticalAlignment); } /** * 默认为内容居中 * @param rowspan 行合并数 * @param colspan 列合并数 * @param text 内容 * @param height 高度 * @param width 宽度 * @param minHeight 最小高度 * @param isDefaultBorder 是否默认边框 * @param border 自定义边框 * @param background 背景色 * @param textAlignment 文字布局 * @param horizontalAlignment 水平布局 * @param verticalAlignment 垂直布局 * @return */ public static Cell cell(int rowspan, int colspan, Paragraph text, float height, float width, float minHeight, boolean isDefaultBorder, Border border, Color background, TextAlignment textAlignment, HorizontalAlignment horizontalAlignment, VerticalAlignment verticalAlignment){ Cell cell = new Cell(rowspan, colspan); if(!isDefaultBorder){ cell.setBorder(border); } if (0 != minHeight){ cell.setMinHeight(minHeight); } if (null != textAlignment){ cell.setTextAlignment(textAlignment); }else{ cell.setTextAlignment(TextAlignment.CENTER); } if (null != horizontalAlignment){ cell.setHorizontalAlignment(horizontalAlignment); }else{ cell.setHorizontalAlignment(HorizontalAlignment.CENTER); } if (null != verticalAlignment){ cell.setVerticalAlignment(verticalAlignment); }else { cell.setVerticalAlignment(VerticalAlignment.MIDDLE); } if (null != background){ cell.setBackgroundColor(background); } if (0 != height){ cell.setHeight(height); } if (0 != width){ cell.setWidth(width); } cell.setKeepTogether(true); cell.add(text); return cell; } /** * 默认数据处理 * @param size * @param defaultValue */ public static void defaultData(Table table, int rowspan, int colspan, int size, String defaultValue){ for(int i =0; i<size; i++){ table.addCell(cell(rowspan, colspan, defaultValue, false)); } } /** * * @param table pdf表格 * @param rowspan 行合并数 * @param colspan 列合并数 * @param colSize 列数 * @param list 数据 * @param t 数据类对象 * @param <T> * @throws Exception */ public static<T> void content(Table table, int rowspan, int colspan, int colSize, List<T> list, Class<T> t) throws Exception{ if (CollectionUtils.isEmpty(list)){ defaultData(table, rowspan, colspan, colSize, "-"); return; } Field[] fields = t.getDeclaredFields(); List<Field> fieldList = Arrays.stream(fields).filter(e->null == e.getAnnotation(IgnoreFiled.class)).sorted((f1, f2)->{ int seq1 = f1.getAnnotation(SeqNo.class).value(); int seq2 = f2.getAnnotation(SeqNo.class).value(); return seq1 - seq2; }).collect(Collectors.toList()); for(T data : list){ for(Field field : fieldList){ field.setAccessible(true); table.addCell(cell(rowspan, colspan, field.get(data), false)); } } } /** * 没有表头的数据 * @param table * @param rowspan * @param colspan * @param colSize * @param datas */ public static void content(Table table, int rowspan, int colspan, int colSize, List<String> datas){ if (CollectionUtils.isEmpty(datas)){ defaultData(table, rowspan, colspan, colSize, "-"); return; } for(String str : datas){ table.addCell(cell(rowspan, colspan, str, false)); } } /** * 处理图片表格数据 * @param table * @param rowspan * @param colspan * @param imageList * @throws Exception */ public static void imageContent(Table table, int rowspan, int colspan, List<String> imageList) throws Exception{ for(String str : imageList){ Image img = ImageHelpers.generateImage(str, true); img.setAutoScale(true); Cell imageCell = new Cell(rowspan,colspan); imageCell.setKeepTogether(true); imageCell.setWidth(img.getWidth()); imageCell.setHeight(img.getImageHeight()); imageCell.setBorder(Border.NO_BORDER); imageCell.add(img); table.addCell(imageCell); } } /** * 结论以及建议表格 * @param table * @param conclusion */ public static void conclusionContent(Table table, String title, String conclusion){ //固定头部信息 Cell headCell = headCell(1, 1, title); headCell.setTextAlignment(TextAlignment.LEFT); table.addHeaderCell(headCell); if (null == conclusion){ conclusion = ""; } table.addCell(cell(1, 1, PDFHelpers.paragraph(conclusion, false), 0, 0, 50).setTextAlignment(TextAlignment.LEFT) .setVerticalAlignment(VerticalAlignment.TOP)); } /** * 生成表格 * @param colSize 列数 * @param height 高度 * @param fixWidth 是否确定宽度 * @param width 宽度 * @param horizontalAlignment 水平对齐方式 * @param verticalAlignment 垂直对齐方式 * @param fixLayOut 是否固定布局 * @return */ public static Table table(int colSize, float height, boolean isFixWidth, float fixWidth, HorizontalAlignment horizontalAlignment, VerticalAlignment verticalAlignment, boolean fixLayOut, float left, float bottom, float width){ Table table = new Table(colSize); if (0 != height){ table.setHeight(height); } if (isFixWidth){ table.setWidth(fixWidth); }else { table.setWidth(UnitValue.createPercentValue(100)); } if (null != horizontalAlignment){ table.setHorizontalAlignment(horizontalAlignment); } if (null != verticalAlignment){ table.setVerticalAlignment(verticalAlignment); } if (fixLayOut){ table.setFixedLayout(); table.setFixedPosition(left, bottom, width); } return table; } }
PDFHelpers 对于一些div, paragraph的统一处理
package com.example.note.pdf; import com.example.note.pdf.domain.PDFStyleContants; import com.itextpdf.kernel.colors.Color; import com.itextpdf.layout.Document; import com.itextpdf.layout.element.*; import com.itextpdf.layout.property.HorizontalAlignment; import com.itextpdf.layout.property.TextAlignment; import com.itextpdf.layout.property.UnitValue; import com.itextpdf.layout.property.VerticalAlignment; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; import java.util.List; /** * @author wqqing * @date 2022/8/26 14:55 */ public class PDFHelpers { /** * div 包含table * @param table 表格 * @param isKeepTogether 是否可断开 * @return */ public static Div div(Table table, boolean isKeepTogether){ Div div = new Div(); div.setKeepTogether(isKeepTogether); div.add(table); return div; } /** * div包裹图片 避免被分割 * @param image * @return */ public static Div div(Image image){ Div div = new Div(); div.setHorizontalAlignment(HorizontalAlignment.CENTER).setVerticalAlignment(VerticalAlignment.MIDDLE).setTextAlignment(TextAlignment.CENTER); div.add(image); return div; } /** * 生成表格 * @param colSize 列数 * @param titles 表头信息 * @param datas 表数据 * @param t 表数据对象 * @param <T> * @return * @throws Exception */ public static<T> Table tablee(int colSize, List<String> titles, List<T> datas, Class<T> t) throws Exception{ Table table = TableHelper.table(colSize, 0, false, 0, null, null, false,0 ,0, 0); TableHelper.header(table,1, 1, titles); TableHelper.content(table, 1, 1, colSize, datas, t); return table; } /** * 没有表头的表数据 * @param colSize 表列数 * @param datas 表数据 * @return * @throws Exception */ public static Table tablee(int colSize, List<String> datas) throws Exception{ Table table = TableHelper.table(colSize, 0, false, 0, null, null, false, 0, 0, 0); TableHelper.content(table, 1, 1, colSize, datas); return table; } /** * 结论与建议代码块 * @param info * @return */ public static Table conclusion(String info){ Table conclusion = new Table(1); conclusion.setWidth(UnitValue.createPercentValue(100)); TableHelper.conclusionContent(conclusion, "结论及建议:", info); return conclusion; } /** * * @param text 内容 * @param bold 是否加粗 * @return */ public static Paragraph paragraph(Object text, boolean bold){ return paragraph(text, 0, bold, false); } /** * * @param text 内容 * @param fontSize 字体 * @param bold 是否加粗 * @return */ public static Paragraph paragraph(Object text, float fontSize, boolean bold){ return paragraph(text, fontSize, bold, true); } /** * 段落处理 * @param text 内容 * @param fontSize 字体大小 * @param bold 是否加粗 * @param indentation 是否缩进 * @return */ public static Paragraph paragraph(Object text, float fontSize, boolean bold, boolean indentation){ return paragraph(text, fontSize, null, bold, indentation); } /** * 段落处理 * @param text 内容 * @param fontSize 字体大小 * @param color 颜色 * @param bold 是否加粗 * @param indentation 是否缩进 * @return */ public static Paragraph paragraph(Object text, float fontSize, Color color, boolean bold, boolean indentation){ Paragraph paragraph = new Paragraph(); paragraph.add(text(text, fontSize, color, bold)); if (indentation){ paragraph.setFirstLineIndent(PDFStyleContants.CONTENT_FONT_SIZE * 2); } paragraph.setMultipliedLeading(1.5f); return paragraph; } public static Text text(Object text, Color color, boolean bold){ return text(text, 0, color, bold); } /** * 特色文本处理 * @param text 内容 * @param color 字体 * @param bold 是否加粗 * @return */ public static Text text(Object text, float fontSize, Color color, boolean bold){ Text result = new Text(String.valueOf(text)); if (null != color){ result.setFontColor(color); } if (0 != fontSize){ result.setFontSize(fontSize); } if (bold){ result.setBold(); } return result; } /** * 图片并排处理 * @param colSize 并列数 * @param images 图片信息 * @return * @throws Exception */ public static Table imageOnLine(int colSize, List<String> images) throws Exception{ Table imageTable = new Table(colSize); TableHelper.imageContent(imageTable, 1, 1, images); return imageTable; } /** * 统一模块处理 * @param document * @param title 标题 * @param desc 描述 * @param colSize 表列数 * @param titles 表头 * @param datas 表数据 * @param t 表数据对象 * @param images 图片信息 * @param conclusion 结论 * @param <T> * @throws Exception */ public static<T> void common(Document document, String title, String desc, int colSize, List<String> titles, List<T> datas, Class<T> t, boolean isKeepTogether, List<String> images, boolean isSingeImage, String conclusion) throws Exception{ if (StringUtils.isNotEmpty(title)){ document.add(paragraph(title, PDFStyleContants.TITLE_FONT_SIZE, true, false)); } if (StringUtils.isNotEmpty(desc)){ document.add(paragraph(desc, 0, false, true)); } if(null != datas){ Div div = div( tablee(colSize, titles, datas, t), isKeepTogether ); document.add(div); } document.add(new Paragraph()); //图片 if (CollectionUtils.isNotEmpty(images)){ if (isSingeImage){//图片单独显示 for(String image : images){ Image image1 = ImageHelpers.generateImage(image, document.getPdfDocument().getDefaultPageSize()); document.add(div(image1)); } }else { //图片并排 document.add(imageOnLine(2, images)); } } document.add(new Paragraph()); //结论以及建议 document.add(conclusion(conclusion)); } }
GeneratePDFReport 生成PDF报告
package com.example.note.pdf; import com.example.note.pdf.domain.Constants; import com.example.note.pdf.domain.PDFStyleContants; import com.example.note.pdf.domain.PdfTestInfo; import com.example.note.pdf.domain.entity.PDFTest; import com.itextpdf.io.font.PdfEncodings; 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.pdf.PdfDocument; import com.itextpdf.kernel.pdf.PdfPage; import com.itextpdf.kernel.pdf.PdfWriter; import com.itextpdf.layout.Canvas; import com.itextpdf.layout.Document; import com.itextpdf.layout.element.AreaBreak; import com.itextpdf.layout.element.Paragraph; import com.itextpdf.layout.property.AreaBreakType; import com.itextpdf.layout.property.TextAlignment; import java.io.FileOutputStream; import java.util.Arrays; /** * @author wqqing * @date 2022/8/25 15:07 */ public class GeneratePDFReport { public static void main(String[] args) { try{ // generatePdf(); }catch (Exception e){ e.printStackTrace(); } } public static void generatePdf(PdfTestInfo info) throws Exception{ FileOutputStream out = new FileOutputStream("D:/test.pdf"); PdfFont pdfFont = PdfFontFactory.createFont(Constants.SONGTI_FONTS_PATH, PdfEncodings.IDENTITY_H); PdfWriter pdfWriter = new PdfWriter(out); PdfDocument pdfDocument = new PdfDocument(pdfWriter); Document document = new Document(pdfDocument, PageSize.A4); document.setMargins(PDFStyleContants.MARGIN_TOP, PDFStyleContants.MARGIN_RIGHT, PDFStyleContants.MARGIN_BOTTOM, PDFStyleContants.MARGIN_LEFT); document.setFont(pdfFont); document.setFontSize(PDFStyleContants.CONTENT_FONT_SIZE); //页眉处理 pdfDocument.addEventHandler(PdfDocumentEvent.END_PAGE, new HeaderFooterHanlder(pdfFont, "页眉测试", "2022年08")); //首页加背景图 commonPage(pdfDocument, document, info.getImage1(), "图片上带有文字", "wqq版权所有"); //表格,图片以及段落处理 handleData(document, info); //强制下一页 document.add(new AreaBreak(AreaBreakType.NEXT_PAGE)); //最后一页 document.add(ImageHelpers.generateBackgroudImage(info.getImage2(), pdfDocument)); document.close(); } private static void handleData(Document document, PdfTestInfo info) throws Exception{ document.add(PDFHelpers.paragraph("标题", 0, true, false)); Paragraph paragraph = new Paragraph(); paragraph.add("测试字体变色处理") .add(PDFHelpers.text("红色了", PDFStyleContants.RED, false)); paragraph.setFirstLineIndent(PDFStyleContants.CONTENT_FONT_SIZE * 2); document.add(paragraph); //图片 PDFHelpers.common(document, null, null, 3, Arrays.asList("名称", "描述", "信息"), info.getTableDatas(), PDFTest.class, true, info.getImages(),false, "结论与建议"); } /** * * @param pdfDocument * @param document * @param desc * @param info * @throws Exception */ private static void commonPage(PdfDocument pdfDocument, Document document, String imagePath, String desc, String info) throws Exception { PdfFont pdfFont = PdfFontFactory.createFont(Constants.YAHEI_FONTS_PATH, PdfEncodings.IDENTITY_H); /**第一页处理**/ document.add(ImageHelpers.generateBackgroudImage(imagePath, pdfDocument)); //文字信息 PdfPage start1 =pdfDocument.getPage(1); Canvas canva1 = new Canvas(start1, start1.getPageSize()); canva1.setFontColor(PDFStyleContants.WHITE) .setFontSize(PDFStyleContants.CONTENT_FONT_SIZE) .setFont(pdfFont) .showTextAligned(new Paragraph().add(desc), 110, 130, TextAlignment.CENTER) .showTextAligned(new Paragraph().add(info), 105, 100, TextAlignment.CENTER); canva1.close(); } }
自己对itext7 也是第一次接触,有啥不对的,请大佬指教,转载请注明文章出处