打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

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

2023.07.18 湖南

关注

1 背景

文章主要通过Java纯后端实现生成PDF源码方案,可以实现PDF表格、图片、统计图及模板!

这里需要用到的技术:JDK8、SpringBoot、POM、lombok、hutool等

2 项目准备

搭建一个SpringBoot项目,这个很简单就不举例了。然后引入pom依赖如下:

<dependency> <groupId>com.itextpdf</groupId> <artifactId>itextpdf</artifactId> <version>5.5.9</version> </dependency> <dependency> <groupId>com.itextpdf</groupId> <artifactId>itext-asian</artifactId> <version>5.2.0</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-core</artifactId> <version>5.4.3</version> <scope>compile</scope> </dependency>

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();        //模板路径,放到项目里用这个ClassPathResource        ClassPathResource 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<BaseFont> 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);        //添加logo        Rectangle 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<BaseFont> 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> 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((i + 1) + '', 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<YqTable> 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 * 页面文档大小,A4,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轴坐标,字体长度也要计算进去 = 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 , 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 , 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 * (j + 1), 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/2 total.showText(foot2);// 模版显示的内容 total.endText(); total.closePath(); }}
  • 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();        //模板路径,放到项目里用这个ClassPathResource        ClassPathResource 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<BaseFont> 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<Reconciliation> 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((i + 1) + '', 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<BeOverdueTable> 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);    }}
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
java根据模板导出pdf
【Itext】7步制作Itext5页眉页脚pdf实现第几页共几页
C# 生成PDF详解(支持中文、水印、页眉、页脚、表格等) | 真有意思
Java POI 生成PDF文档,很给力!
Java 使用 iText动态生成PDF文档
使用IText打印PDF
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服