Java后端生成PDF源码方案,PDF表格、图片、统计图及模板全都有!


Java后端生成PDF源码方案,PDF表格、图片、统计图及模板全都有!

1 背景

文章主要通过Java纯后端实现生成PDF源码方案,可以实现PDF表格、图片、统计图及模板!
这里需要用到的技术:JDK8、SpringBoot、POM、lombok、hutool等


2 项目准备

搭建一个SpringBoot项目,这个很简单就不举例了 。然后引入pom依赖如下:
com.itextpdfitextpdf5.5.9com.itextpdfitext-asian5.2.0 org.projectlomboklombokcn.hutoolhutool-core5.4.3compile


3 JAVA根据已有的pdf模板 , 填充数据生成pdf(图片及动态生成表格)

  • 实体类
对账实体
package com.test.merservice.controller.miniapp;import lombok.Data;import lombok.experimental.Accessors;import java.math.BigDecimal;/** *对账 */@Data@Accessors(chain = true)public class Reconciliation {private String jg;private Integer ydz;private Integer wdz;private BigDecimal dzl;}
逾期表格实体
package com.test.merservice.controller.miniapp;import lombok.Data;import lombok.experimental.Accessors;import java.io.Serializable;/** *逾期表格 */@Data@Accessors(chain = true)public class BeOverdueTable implements Serializable {private String jg;private Integer yqs;}
  • 填充数据到已有模板,并PDF代码
package com.test.merservice.controller.miniapp;import cn.hutool.core.date.DateUtil;import com.example.demo.domain.DuizhangDomain;import com.example.demo.domain.YqTable;import com.example.demo.pdf.phantom.App;import com.example.demo.pdf.phantom.PageEvent;import com.itextpdf.text.*;import com.itextpdf.text.pdf.*;import freemarker.template.TemplateException;import org.springframework.core.io.ClassPathResource;import javax.servlet.http.HttpServletResponse;import java.io.ByteArrayOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.math.BigDecimal;import java.util.ArrayList;import java.util.List;/** * 动态生成PDF */public class CreatePdfEchrtsAndTable {private final static String TITLE = "标题";public void createPdfFile(HttpServletResponse response) throws IOException, DocumentException, TemplateException {//设置请求返回类型response.setHeader("Content-Disposition", "attachment; filename=对账测试.pdf");OutputStream outputStream = response.getOutputStream();//模板路径 , 放到项目里用这个ClassPathResourceClassPathResource classPathResource = new ClassPathResource("templates/模板.pdf");InputStream inputStream = classPathResource.getInputStream();PdfReader reader = new PdfReader(inputStream);ByteArrayOutputStream bos = new ByteArrayOutputStream();PdfStamper ps = new PdfStamper(reader, bos);//设置字体final BaseFont font = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);ArrayList fontList = new ArrayList<>();fontList.add(font);//提取表单,这个是模板画好的文本框AcroFields s = getAcroFields(ps, font, fontList);//添加图片PdfContentByte cb = getPdfContentByte(ps, s);//获取统计图extracted(s, cb);//按机构统计图byte[] echarts = getBytes(font, s, cb);//按场合统计图extracted(font, s, cb, echarts);//按等级统计图extracted(ps, font, s, cb, echarts);//*******************填充编辑好后的pdf**************reader = new PdfReader(bos.toByteArray());Rectangle pageSize = reader.getPageSize(1);Document document = new Document(pageSize);PdfWriter writer = PdfWriter.getInstance(document, outputStream);writer.setPageEvent(new PageEvent());// 打开文档document.open();PdfContentByte cbUnder = writer.getDirectContentUnder();PdfImportedPage pageTemplate = writer.getImportedPage(reader, 1);cbUnder.addTemplate(pageTemplate, 0, 0);//重新开一页面(注意一下,这里必须要重新开一个页面,不如会导致内容重叠)document.newPage();createTable(writer,document);//document.newPage();createTableYq(writer,document);document.close();outputStream.close();}private void extracted(PdfStamper ps, BaseFont font, AcroFields s, PdfContentByte cb, byte[] echarts) {Rectangle adj = s.getFieldPositions("adj").get(0).position;Image adjImage = Image.getInstance(echarts);// 设根据域大小设置缩放图片adjImage.scaleToFit(adj.getWidth(),400);// 设置居中adjImage.setAlignment(Image.MIDDLE);// 绝对定位adjImage.setAbsolutePosition(adj.getLeft(),adj.getBottom());cb.addImage(adjImage);//按场景排名for (int i = 1; i <= 3; i) {s.setFieldProperty("adj"i,"textfont", font,null);s.setField("adj"i,"机构"i);}ps.setFormFlattening(true);ps.close();}private void extracted(BaseFont font, AcroFields s, PdfContentByte cb, byte[] echarts) {Rectangle acj = s.getFieldPositions("acj").get(0).position;Image acjImage = Image.getInstance(echarts);// 设根据域大小设置缩放图片acjImage.scaleToFit(acj.getWidth(), 400);// 设置居中acjImage.setAlignment(Image.MIDDLE);// 绝对定位acjImage.setAbsolutePosition(acj.getLeft(),acj.getBottom());cb.addImage(acjImage);//按场景排名for (int i = 1; i <= 3; i) {s.setFieldProperty("acj"i,"textfont", font,null);s.setField("acj"i,"机构"i);}}private byte[] getBytes(BaseFont font, AcroFields s, PdfContentByte cb) {//这个是生成echarts的类,如果需要生成echarts可以去看我的另一个文章,上面前言已经提到了App app1 = new App();byte[] echarts1 = app1.createEcharts("ajg.ftl");Image ajgImage = Image.getInstance(echarts1);Rectangle ajg = s.getFieldPositions("ajg").get(0).position;// 根据域大小设置缩放图片ajgImage.scaleToFit(ajg.getWidth(),400);// 设置居中ajgImage.setAlignment(Image.MIDDLE);// 绝对定位ajgImage.setAbsolutePosition(ajg.getLeft(),ajg.getBottom());cb.addImage(ajgImage);//按机构排名,这个是在图片的基础上还要添加数据,这个模板可以画好for (int i = 1; i <= 3; i) {s.setFieldProperty("ajg"i,"textfont", font,null);s.setField("ajg"i,"机构"i);}App app = new App();byte[] echarts = app.createEcharts("option.ftl");//按业务Rectangle ayw = s.getFieldPositions("ayw").get(0).position;Image aywImage = Image.getInstance(echarts);// 设根据域大小设置缩放图片aywImage.scaleToFit(ayw.getWidth(), 400);// 设置居中aywImage.setAlignment(Image.MIDDLE);// 绝对定位aywImage.setAbsolutePosition(ayw.getLeft(),ayw.getBottom());cb.addImage(aywImage);//按业务排名for (int i = 1; i <= 3; i) {s.setFieldProperty("ayw"i,"textfont", font,null);s.setField("ayw"i,"机构"i);}return echarts;}private void extracted(AcroFields s, PdfContentByte cb) {//获取域Rectangle rlt = s.getFieldPositions("rlt").get(0).position;//热力图Image rltImage = Image.getInstance("https://img0.baidu.com/it/u=4043177345,1055141017&fm=253&app=138&size=w931&n=0&f=PNG&fmt=auto?sec=1668186000&t=8cfdc5c95cc0070eb91946d780ee8dc3");//根据域大小设置缩放图片rltImage.scaleToFit(rlt.getWidth()100,rlt.getHeight());// 设置居中rltImage.setAlignment(Image.MIDDLE);//绝对定位rltImage.setAbsolutePosition(rlt.getLeft(),rlt.getBottom());//图片旋转,这个可以将图片进行一个旋转,看自己需求//rltImage.setRotationDegrees(90);cb.addImage(rltImage);}private PdfContentByte getPdfContentByte(PdfStamper ps, AcroFields s) {PdfContentByte cb = ps.getOverContent(1);//添加logoRectangle logo = s.getFieldPositions("logo").get(0).position;Image logoImage = Image.getInstance("https://img1.baidu.com/it/u=3646261857,3326755268&fm=253&app=138&size=w931&n=0&f=JPG&fmt=auto?sec=1668186000&t=20050fc88fc3feb1f9d28392f4595ec6");//根据域的大小缩放图片,我这里宽度在原有的域基础上加了100,你们可以自己调节logoImage.scaleToFit(logo.getWidth()100,logo.getHeight());logoImage.setAlignment(Image.MIDDLE);logoImage.setAbsolutePosition(logo.getLeft(),logo.getBottom());cb.addImage(logoImage);return cb;}private AcroFields getAcroFields(PdfStamper ps, BaseFont font, ArrayList fontList) {AcroFields s = ps.getAcroFields();s.setSubstitutionFonts(fontList);s.setFieldProperty("jrfk","textfont", font,null);s.setFieldProperty("bjzs","textfont", font,null);s.setFieldProperty("type","textfont", font,null);s.setFieldProperty("createTime","textfont", font,null);s.setFieldProperty("title","textfont", font,null);s.setField("jrfk","10");s.setField("bjzs","20");s.setField("type","日报");s.setField("createTime", DateUtil.now());s.setField("title", TITLE);return s;}//为一个表格添加内容public PdfPCell createSetCell(String value,Font font){PdfPCell cell = new PdfPCell();cell.setPhrase(new Phrase(value,font));cell.setVerticalAlignment(Element.ALIGN_MIDDLE);cell.setHorizontalAlignment(Element.ALIGN_CENTER);return cell;}//添加表格public void createTable(PdfWriter writer,Document document) throws DocumentException, IOException {PdfPTable table = new PdfPTable(new float[] { 30, 80, 50, 50, 50});table.setTotalWidth(520);table.setPaddingTop(500);table.setLockedWidth(true);table.setHorizontalAlignment(Element.ALIGN_CENTER);//居中table.writeSelectedRows(0, -1,500,800,writer.getDirectContentUnder());//每页都显示表头,输入几就是第几行的表头固定table.setHeaderRows(2);table.setHeaderRows(3);//定义数据的字体BaseFont baseFont = BaseFont.createFont("STSong-Light","UniGB-UCS2-H",BaseFont.NOT_EMBEDDED);Font textFont = new Font(baseFont, 10, Font.NORMAL);PdfPCell cell = new PdfPCell(new Paragraph(" ", textFont));cell.setHorizontalAlignment( Element.ALIGN_LEFT);cell.setVerticalAlignment(Element.ALIGN_BOTTOM);cell.setBorder(Rectangle.NO_BORDER);cell.setColspan(5);table.addCell(cell);//表头信息PdfPCell heandCell = new PdfPCell();heandCell.setRowspan(1);heandCell.setColspan(5);heandCell.setFixedHeight(60);heandCell.setVerticalAlignment(Element.ALIGN_MIDDLE);heandCell.setHorizontalAlignment(Element.ALIGN_CENTER);heandCell.setPhrase(new Phrase(TITLE"对账情况表",textFont));table.addCell(heandCell);//表字段String title[] = {"序号","机构","已对账","未对账","对账率%"};for (int i = 0; i < title.length; i) {PdfPCell heardCell = new PdfPCell();heardCell.setVerticalAlignment(Element.ALIGN_MIDDLE);heardCell.setHorizontalAlignment(Element.ALIGN_CENTER);heardCell.setPhrase(new Phrase(title[i], textFont));heardCell.setMinimumHeight(20);table.addCell(heardCell);}//列表数据List reconciliation = new ArrayList<>();for (int i = 1; i <= 1000; i) {Reconciliation reconciliation = new Reconciliation();reconciliation.setJg("机构"i).setYdz(i).setWdz(i).setDzl(new BigDecimal(i));reconciliation.add(reconciliation);}for (int i = 0; i < reconciliation.size(); i) {PdfPCell setCell1 = createSetCell((i1)"", textFont);PdfPCell setCell2 = createSetCell(reconciliation.get(i).getJg(), textFont);PdfPCell setCell3 = createSetCell(reconciliation.get(i).getYdz().toString(), textFont);PdfPCell setCell4 = createSetCell(reconciliation.get(i).getWdz().toString(), textFont);PdfPCell setCell5 = createSetCell(reconciliation.get(i).getDzl()"%", textFont);table.addCell(setCell1);table.addCell(setCell2);table.addCell(setCell3);table.addCell(setCell4);table.addCell(setCell5);}document.add(table);}public void createTableYq(PdfWriter writer,Document document) throws DocumentException, IOException {PdfPTable table = new PdfPTable(new float[] {80, 50});table.setTotalWidth(520);table.setPaddingTop(500);table.setLockedWidth(true);table.setHorizontalAlignment(Element.ALIGN_CENTER);//居中table.writeSelectedRows(0, -1,500,800,writer.getDirectContentUnder());//每页都显示表头,输入几就是第几行的表头固定table.setHeaderRows(2);table.setHeaderRows(3);//定义数据的字体BaseFont baseFont = BaseFont.createFont("STSong-Light","UniGB-UCS2-H",BaseFont.NOT_EMBEDDED);Font textFont = new Font(baseFont, 10, Font.NORMAL);//这个是为了区分两个表格加的一个间隔,可以去掉PdfPCell cell = new PdfPCell(new Paragraph(" ", textFont));cell.setHorizontalAlignment( Element.ALIGN_LEFT);cell.setVerticalAlignment(Element.ALIGN_BOTTOM);cell.setBorder(Rectangle.NO_BORDER);cell.setColspan(2);table.addCell(cell);//表头信息PdfPCell heandCell = new PdfPCell();heandCell.setRowspan(1);heandCell.setColspan(2);heandCell.setFixedHeight(60);heandCell.setVerticalAlignment(Element.ALIGN_MIDDLE);heandCell.setHorizontalAlignment(Element.ALIGN_CENTER);heandCell.setPhrase(new Phrase(TITLE"逾期表",textFont));table.addCell(heandCell);//表字段String title[] = {"机构名称","逾期数"};for (int i = 0; i < title.length; i) {PdfPCell heardCell = new PdfPCell();heardCell.setVerticalAlignment(Element.ALIGN_MIDDLE);heardCell.setHorizontalAlignment(Element.ALIGN_CENTER);heardCell.setPhrase(new Phrase(title[i], textFont));heardCell.setMinimumHeight(20);table.addCell(heardCell);}//列表数据List yqTables = new ArrayList<>();for (int i = 1; i <= 1000; i) {BeOverdueTable yq = new BeOverdueTable();yq.setJg("逾期机构"i).setYqs(i);yqTables.add(yq);}for (int i = 0; i < yqTables.size(); i) {PdfPCell setCell2 = createSetCell(yqTables.get(i).getJg(), textFont);PdfPCell setCell3 = createSetCell(yqTables.get(i).getYqs().toString(), textFont);table.addCell(setCell2);table.addCell(setCell3);}document.add(table);}}
注意:Document.document.newPage(); 每次都新打开一页 , 这样可以避免内容重叠 。


4 JAVA根据已有模板,填充数据生成pdf(水印动态表格)

  • 实体同上不变
  • 页眉、页脚和水印工具类
package com.test.merservice.controller.miniapp;import com.itextpdf.text.*;import com.itextpdf.text.pdf.*;import java.io.IOException;/** * 页眉、页脚、水印 */public class PdfPageEvent extends PdfPageEventHelper {/*** 页眉*///public String header = "测试页眉";/*** 文档字体大小,页脚页眉最好和文本大小一致*/public int presentFontSize = 10;/*** 文档页面大小,最好前面传入,否则默认为A4纸张*/public Rectangle pageSize = PageSize.A4;// 模板public PdfTemplate total;// 基础字体对象public BaseFont bf = null;// 利用基础字体生成的字体对象,一般用于生成中文文字public Font fontDetail = null;/*** 无参构造方法.*/public PdfPageEvent() {}/*** 构造方法.* @param presentFontSize*数据体字体大小* @param pageSize*页面文档大?。珹4,A5,A6横转翻转等Rectangle对象*///public PDFBuilder(String yeMei, int presentFontSize, Rectangle pageSize) {//this.header = yeMei;//this.presentFontSize = presentFontSize;//this.pageSize = pageSize;//}public PdfPageEvent(int presentFontSize, Rectangle pageSize) {this.presentFontSize = presentFontSize;this.pageSize = pageSize;}//public void setHeader(String header) {//this.header = header;//}public void setPresentFontSize(int presentFontSize) {this.presentFontSize = presentFontSize;}/**** 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.addWatermark(writer);}//加分页public void addPage(PdfWriter writer, Document document){//设置分页页眉页脚字体try {if (bf == null) {bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", false);}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);//页眉添加图片//String path = ResourceUtils.getFile("classpath:").getPath();//Image img = Image.getInstance(path"/pdfTemplates/logo.jpg");//img.setAlignment(Image.MIDDLE);//img.setWidthPercentage(80);//img.scaleToFit(50,40);//img.setAbsolutePosition(document.left(),document.top());//writer.getDirectContent().addImage(img);//页眉加下划线//PdfPTable tableHeader = new PdfPTable(1);//tableHeader.setTotalWidth(PageSize.A4.getWidth() - 60);//PdfPCell pCell = new PdfPCell();//pCell.setBorderWidthBottom(0.3f);//tableHeader.addCell(pCell);//tableHeader.writeSelectedRows(0, -1, 30, 805, writer.getDirectContent());// 2.写入前半部分的 第 X页/共int pageS = writer.getPageNumber();String foot1 = "第 "pageS" 页 /共";//String foot1 = pageS"/";Phrase footer = new Phrase(foot1, fontDetail);// 3.计算前半部分的foot1的长度,后面好定位最后一部分的'Y页'这俩字的x轴坐标,字体长度也要计算进去 = lenfloat len = bf.getWidthPoint(foot1, presentFontSize);// 4.拿到当前的PdfContentBytePdfContentByte cb = writer.getDirectContent();// 5.写入页脚1 , x轴就是(右margin 左marginright() -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 ,document.bottom() - 20, 0);// 6.写入页脚2的模板(就是页脚的Y页这俩字)添加到文档中,计算模板的和Y轴,X=(右边界-左边界 - 前半部分的len值)/2.0F// len,y 轴和之前的保持一致,底边界-20cb.addTemplate(total, (document.rightMargin()document.right()document.leftMargin() - document.left()) / 2.0F ,document.bottom() - 20); // 调节模版显示的位置}//加水印public void addWatermark(PdfWriter writer) {// 水印图片//Image image;//try {//image = Image.getInstance("./web/images/001.jpg");//PdfContentByte content = writer.getDirectContentUnder();//content.beginText();//// 开始写入水印//for(int k=0;k<5;k){//for (int j = 0; j <4; j) {//image.setAbsolutePosition(150*j,170*k);//content.addImage(image);//}//}//content.endText();//} catch (IOException | DocumentException e) {//// TODO Auto-generated catch block//e.printStackTrace();//}BaseFont font = null;try {font = BaseFont.createFont("STSong-Light","UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);} catch (DocumentException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}PdfGState gs = new PdfGState();//添加透明度gs.setFillOpacity(0.4f);PdfContentByte content = writer.getDirectContentUnder();content.beginText();//水印颜色content.setColorFill(BaseColor.DARK_GRAY);content.setGState(gs);//水印字体样式和大小content.setFontAndSize(font, 35);//插入水印循环每页插入的条数for (int j = 0; j < 3; j) {content.showTextAligned(Element.ALIGN_CENTER, "锦鲤飞上天测试水印", 300, 200 * (j1), 30);}content.endText();}/**** 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())" 页"; //页脚内容拼接如第1页/共2页//String foot2 = String.valueOf(writer.getPageNumber()); //页脚内容拼接如1/2total.showText(foot2);// 模版显示的内容total.endText();total.closePath();}}
  • PDF生成
【Java后端生成PDF源码方案,PDF表格、图片、统计图及模板全都有!】package com.sllt.merservice.controller.miniapp;import cn.hutool.core.date.DateUtil;import com.example.demo.domain.DuizhangDomain;import com.example.demo.domain.YqTable;import com.example.demo.pdf.phantom.PageEvent;import com.itextpdf.text.*;import com.itextpdf.text.pdf.*;import freemarker.template.TemplateException;import org.springframework.core.io.ClassPathResource;import javax.servlet.http.HttpServletResponse;import java.io.ByteArrayOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.math.BigDecimal;import java.util.ArrayList;import java.util.List;/** * 模板第一页不占满,生成表格 */public class CreatePdfEchrtsAndTableTwo {public void createPdfFile(HttpServletResponse response) throws IOException, DocumentException, TemplateException {//设置请求返回类型response.setHeader("Content-Disposition", "attachment; filename=测试.pdf");OutputStream outputStream = response.getOutputStream();//模板路径 , 放到项目里用这个ClassPathResourceClassPathResource classPathResource = new ClassPathResource("templates/test3.pdf");InputStream inputStream = classPathResource.getInputStream();PdfReader reader = new PdfReader(inputStream);ByteArrayOutputStream bos = new ByteArrayOutputStream();PdfStamper ps = new PdfStamper(reader, bos);//设置字体final BaseFont font = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);ArrayList fontList = new ArrayList<>();fontList.add(font);//提取表单AcroFields s = ps.getAcroFields();s.setSubstitutionFonts(fontList);s.setFieldProperty("type", "textfont", font, null);s.setFieldProperty("createTime", "textfont", font, null);s.setFieldProperty("title", "textfont", font, null);s.setField("type", "日报");s.setField("createTime", DateUtil.now());s.setField("title", "这是title,模板画的位置框");ps.setFormFlattening(true);ps.close();//*******************填充编辑好后的pdf**************reader = new PdfReader(bos.toByteArray());Rectangle pageSize = reader.getPageSize(1);Document document = new Document(pageSize);PdfWriter writer = PdfWriter.getInstance(document, outputStream);writer.setPageEvent(new PageEvent());// 打开文档document.open();PdfContentByte cbUnder = writer.getDirectContentUnder();PdfImportedPage pageTemplate = writer.getImportedPage(reader, 1);cbUnder.addTemplate(pageTemplate, 0, 0);//添加间隙,这里为进行了一个封装 , 因为这个模板第一页只有一些title啥的,//重开一页太浪费,只需要确定表格要在什么位置生成,添加一个间隙就可以了createBlankTable(writer, document, font, 180);createTable(writer, document);createBlankTable(writer, document, font, 20);createTableYq(writer, document);document.close();outputStream.close();}//为一个表格添加内容public PdfPCell createSetCell(String value, Font font) {PdfPCell cell = new PdfPCell();cell.setPhrase(new Phrase(value, font));cell.setVerticalAlignment(Element.ALIGN_MIDDLE);cell.setHorizontalAlignment(Element.ALIGN_CENTER);return cell;}//添加表格public void createTable(PdfWriter writer, Document document) throws DocumentException, IOException {PdfPTable table = new PdfPTable(new float[]{30, 80, 50, 50, 50});table.setTotalWidth(520);table.setPaddingTop(500);table.setLockedWidth(true);table.setHorizontalAlignment(Element.ALIGN_CENTER);//居中table.writeSelectedRows(0, -1, 500, 800, writer.getDirectContentUnder());//每页都显示表头,输入几就是第几行的表头固定table.setHeaderRows(1);table.setHeaderRows(2);//定义数据的字体BaseFont baseFont = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);Font textFont = new Font(baseFont, 10, Font.NORMAL);//表头信息PdfPCell heandCell = new PdfPCell();heandCell.setRowspan(1);heandCell.setColspan(5);heandCell.setFixedHeight(30);heandCell.setVerticalAlignment(Element.ALIGN_MIDDLE);heandCell.setHorizontalAlignment(Element.ALIGN_CENTER);heandCell.setPhrase(new Phrase("对账情况表", textFont));table.addCell(heandCell);//表字段String title[] = {"序号", "机构", "已对账", "未对账", "对账率%"};for (int i = 0; i < title.length; i) {PdfPCell heardCell = new PdfPCell();heardCell.setRowspan(1);heardCell.setVerticalAlignment(Element.ALIGN_MIDDLE);heardCell.setHorizontalAlignment(Element.ALIGN_CENTER);heardCell.setPhrase(new Phrase(title[i], textFont));heardCell.setMinimumHeight(20);table.addCell(heardCell);}//列表数据List duizhangDomains = new ArrayList<>();for (int i = 1; i <= 1000; i) {Reconciliation reconciliation = new Reconciliation();reconciliation.setJg("机构"i).setYdz(i).setWdz(i).setDzl(new BigDecimal(i));duizhangDomains.add(reconciliation);}for (int i = 0; i < duizhangDomains.size(); i) {PdfPCell setCell1 = createSetCell((i1)"", textFont);PdfPCell setCell2 = createSetCell(duizhangDomains.get(i).getJg(), textFont);PdfPCell setCell3 = createSetCell(duizhangDomains.get(i).getYdz().toString(), textFont);PdfPCell setCell4 = createSetCell(duizhangDomains.get(i).getWdz().toString(), textFont);PdfPCell setCell5 = createSetCell(duizhangDomains.get(i).getDzl()"%", textFont);table.addCell(setCell1);table.addCell(setCell2);table.addCell(setCell3);table.addCell(setCell4);table.addCell(setCell5);}document.add(table);}public void createTableYq(PdfWriter writer, Document document) throws DocumentException, IOException {PdfPTable table = new PdfPTable(new float[]{80, 50});table.setTotalWidth(520);table.setPaddingTop(500);table.setLockedWidth(true);table.setHorizontalAlignment(Element.ALIGN_CENTER);//居中table.writeSelectedRows(0, -1, 500, 800, writer.getDirectContentUnder());//每页都显示表头,输入几就是第几行的表头固定table.setHeaderRows(2);table.setHeaderRows(3);//定义数据的字体BaseFont baseFont = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);Font textFont = new Font(baseFont, 10, Font.NORMAL);//表头信息PdfPCell heandCell = new PdfPCell();heandCell.setRowspan(1);heandCell.setColspan(2);heandCell.setFixedHeight(30);heandCell.setVerticalAlignment(Element.ALIGN_MIDDLE);heandCell.setHorizontalAlignment(Element.ALIGN_CENTER);heandCell.setPhrase(new Phrase("逾期表", textFont));table.addCell(heandCell);//表字段String title[] = {"机构名称", "逾期数"};for (int i = 0; i < title.length; i) {PdfPCell heardCell = new PdfPCell();heardCell.setVerticalAlignment(Element.ALIGN_MIDDLE);heardCell.setHorizontalAlignment(Element.ALIGN_CENTER);heardCell.setPhrase(new Phrase(title[i], textFont));heardCell.setMinimumHeight(20);table.addCell(heardCell);}//列表数据List yqTables = new ArrayList<>();for (int i = 1; i <= 1000; i) {BeOverdueTable yq = new BeOverdueTable();yq.setJg("逾期机构"i).setYqs(i);yqTables.add(yq);}for (int i = 0; i < yqTables.size(); i) {PdfPCell setCell2 = createSetCell(yqTables.get(i).getJg(), textFont);PdfPCell setCell3 = createSetCell(yqTables.get(i).getYqs().toString(), textFont);table.addCell(setCell2);table.addCell(setCell3);}document.add(table);}/*** 创建表格跟表格之间的空白间隔*/public void createBlankTable(PdfWriter writer, Document document, BaseFont font, int height) throws DocumentException {PdfPTable table = new PdfPTable(new float[]{30});table.setTotalWidth(520);table.setPaddingTop(500);table.setLockedWidth(true);table.setHorizontalAlignment(Element.ALIGN_CENTER);//居中table.writeSelectedRows(0, -1, 500, 800, writer.getDirectContentUnder());Font textFont = new Font(font, 10, Font.NORMAL);PdfPCell cell = new PdfPCell(new Paragraph(" ", textFont));cell.setHorizontalAlignment(Element.ALIGN_LEFT);cell.setVerticalAlignment(Element.ALIGN_BOTTOM);cell.setBorder(Rectangle.NO_BORDER);cell.setFixedHeight(height);cell.setColspan(1);table.addCell(cell);document.add(table);}}

相关经验推荐