首页 > 编程语言 >小吴讲故事之假如我有100w(java生成pdf文档,一页A4多条数据)

小吴讲故事之假如我有100w(java生成pdf文档,一页A4多条数据)

时间:2024-06-15 17:29:32浏览次数:18  
标签:java ALIGN Element Paragraph PdfPCell new 100w pdf body4

故事背景

各位码农们好!我是在社会接受练习时长2年半的java练习生,大家也可以叫我小卡拉米 吴!最近在项目中遇到一个需求,就是有关于pdf文件生成的,具体需求如下。

到了小卡拉米 吴讲故事的时间了:

事情是这样的。

小吴是一名普通的码农,和野原广志一样,但不是小组长,生活除了工作就是回家。

突然,在某一天的加班的晚上,小王加班很晚,结束了一天的工作,身体甚是乏困呀!在边走的路上,嘴里还在对自己的领导:什么傻*领导,加nm破班!买nm的命!若是老子富德流油,绝对踩你桌子,睡觉掀你被子!后来用jio踢飞一个小石子,结果踢中了一个阿拉丁神灯,结果冒出来一个河神。

河神突然问道:骂骂赖赖的年轻人啊~,你踢的是这个金石头还是这个银石头呢,。

小吴回道:你跟我玩呢,这三个都是普通石头,金石头和银石头,刷漆还没干,赶紧的赔我100W,损塞。

河神,指了指路灯下草丛旁的方向,在那边有100W。小吴顺势的走向那个方向,打开草丛,果真有100w,于是把钱塞在装电脑的背包,把吃饭的家伙 (某想thinkPad 老win10)丢掉,飞奔往家里跑。

为了不让人怀疑,小吴在这接下来的几个月以10w的额度存入银行,对于银行来说,是一笔大额存单,于是以VIP待遇服务小吴,服务办理流畅,小吴给了五星好评。在这一年里,小吴吃着利润在家养着,后来去银行PC端打了电子凭证,结果批量打凭证的时候,打了10张,小吴嫌繁琐,就问客服能不能把这些凭证尽量放在一个A4里去呢。结果银行说,只能打一张呀。

需求分析

小吴去银行查询凭证,想要将这一年的凭证批量打印下来,想把这些凭证数据尽量放在一页纸上。

功能实现分析

需要实现这样的需求,有以下这几种思考:

准备:基础生成单页的pdf代码已经实现

实际思考:将尽量数据塞在一页的a4纸域,那么用document.newPage()方法生成新的pdf页面,然后循环继续塞入,对于一页塞多少个,需要在循环进行处理。

功能实现方式:

1.通过画模版,用代码填充

你可以通过制作pdf模版的方式进行处理,然后根据pdf文本域通过代码进行填充,缺点就是需要画模版,生产模版后的数据过长可能会导致数据展示一半的情况。

2.通过代码生成

total:总数据条数

pageSizeNum:A4页面设定的条数(一个A4塞多少条)

代码生成需要考虑怎样塞入一个A4域,并且如何处理,最后一页小于设定pageSizeNum。

最后一页数据条数,我们可以用取余的方式total%pageSizeNum进行判断。

1)希尔排序

你可以使用排序算法处理一页塞入多少个数据,用到希尔排序,根据页面条数进行希尔排序放入,这样就不需要考虑最后一页。

2)计数器

在循环插入数据是,用一个计数器的方式进行实现,也不用考虑最后一页,计数器计数count==pageSizeNum时,生产新的document.newPage()页面,并将恢复默认为0.

3)先分页,再处理最后一页 (这样有点复杂,需要最后一页的数据条数,可以写递归方法进行实现)

代码实现

这里用代码生成pdf,采用计数器方式比较便捷,其他方式各位可以自己实现,这边提供思路。

依赖:

  <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itextpdf</artifactId>
            <version>5.5.13</version>
        </dependency>
        <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itext-pdfa</artifactId>
            <version>5.5.13</version>
        </dependency>
        <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itext-asian</artifactId>
            <version>5.2.0</version>
        </dependency>
        <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>layout</artifactId>
            <version>7.2.3</version>
        </dependency>

代码实现:

package com.wujz.test.util;

import com.itextpdf.text.*;
import com.itextpdf.text.pdf.*;

import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class OtherModel {

    public static void main(String[] args) {
        Map<String, Object> taxPayList = new HashMap<>();
        taxPayList.put("ELEC_BACK_DOC_NUM", "123456789123456789");
        //数据总数
        int total=10;
        //页面条数 一页1-3条
        int pageNumSize=1;
        //生成pdf页数 10/3=4页
        try {
            //创建文档对象
            Document document = new Document(PageSize.A4);
            //导出的地址
            PdfWriter.getInstance(document, new FileOutputStream("D:\\pdfOut\\otherModel_test_1.pdf"));
            //打开文档
            document.open();

            //中文字体,解决中文不能显示问题
            //BaseFont bfChinese = BaseFont.createFont("STSong-Light","UniGB-UCS2-H",BaseFont.NOT_EMBEDDED);
            BaseFont bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
            Font blueFont = new Font(bfChinese, 14, Font.BOLD);
            //设置字体黑色
            blueFont.setColor(BaseColor.BLACK);

            Font blueFont1 = new Font(bfChinese, 12, Font.BOLD);
            //字体颜色
            blueFont1.setColor(BaseColor.BLACK);

            //设置字体黑色
            Font fontValueBody = new Font(bfChinese);
            fontValueBody.setColor(BaseColor.BLACK);
            fontValueBody.setSize(8);
            Font fontValueLabelBody = new Font(bfChinese, 8, Font.BOLD);
            //
            Font fontValue = new Font(bfChinese);
            fontValue.setColor(BaseColor.BLACK);
            fontValue.setSize(9f);
            int pageNumSizeCount=0;
//核心处理逻辑
            for(int i=0;i<total;i++) {
                //计数器 计数添加在页面的数为a4的最大页面数
                pageNumSizeCount+=1;
                pdfContent(document, taxPayList, blueFont, blueFont1, fontValueBody);
                if(pageNumSizeCount==pageNumSize){
                    document.newPage();
                    pageNumSizeCount=0;
                }

            }
            document.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    private static void pdfContent(Document document, Map<String, Object> pdfFillContent, Font blueFont, Font blueFont1, Font fontValueBody) throws DocumentException {
        //pdfContent start
        Paragraph paragraph1 = new Paragraph("XX银行单位定期存单电子凭证", blueFont);
        Paragraph paragraph = new Paragraph();
        //设置段落前后间距
        paragraph1.setSpacingAfter(20);
        //设置段段落居中
        paragraph1.setAlignment(Element.ALIGN_CENTER);
        document.add(paragraph1);

        //定义段落

        Paragraph paragraphL = new Paragraph("", blueFont1);
        Paragraph paragraphR = new Paragraph();
        Phrase elecDocNumLabel = new Phrase("电子凭证编号:", blueFont1);
        //Phrase elecDocNum=new Phrase(taxPayList.get("ELEC_BACK_DOC_NUM").toString(),fontValueLabelBody);
        Phrase elecDocNum = new Phrase(pdfFillContent.get("ELEC_BACK_DOC_NUM").toString(), blueFont1);

        paragraphR.add(elecDocNumLabel);
        paragraphR.add(elecDocNum);
        //设置段落前后间距
        paragraphL.setLeading(0);
        paragraphL.setAlignment(0);
        paragraphR.setLeading(0);
        paragraphR.setAlignment(2);
        //设置段段落居中

        paragraph.add(paragraphL);
        paragraph.add(paragraphR);
        paragraph.setSpacingAfter(18);
        document.add(paragraph);


        //LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));

        //定义列数
        int tableBodyFlag = 15;
        // 创建表对象
        PdfPTable tableBody = new PdfPTable(tableBodyFlag);
        //居中对齐
        tableBody.setHorizontalAlignment(Element.ALIGN_CENTER);
        tableBody.setWidthPercentage(100); // 宽度100%填充
        float[] columnWidths1 = {0.15f,0.1f,0.15f,0.09f,0.1f,0.05f,0.09f,0.1f,0.15f,0.09f,0.1f,0.05f,0.09f,0.09f,0.1f};
        tableBody.setWidths(columnWidths1);

        //设置行对象
        ArrayList<PdfPRow> listRowBody = tableBody.getRows();
        //第一行
        PdfPCell body1[] = new PdfPCell[tableBodyFlag];
        Paragraph paragraph10 = new Paragraph("你单位已在我行开立单位定期存单。", fontValueBody);

        body1[0] = new PdfPCell(paragraph10);//单元格内容
        body1[0].setColspan(15);
        body1[0].setHorizontalAlignment(Element.ALIGN_CENTER);
        body1[0].setVerticalAlignment(Element.ALIGN_MIDDLE);
        body1[0].setMinimumHeight(15);
        PdfPRow rowBody1 = new PdfPRow(body1);

        PdfPCell body2[] = new PdfPCell[tableBodyFlag];
        Paragraph paragraph20 = new Paragraph("户名", fontValueBody);
        Paragraph paragraph21 = new Paragraph("户名", fontValueBody);
        Paragraph paragraph22 = new Paragraph("开户日期", fontValueBody);
        Paragraph paragraph23 = new Paragraph("开户日期", fontValueBody);
        body2[0] = new PdfPCell(paragraph20);//单元格内容
        body2[1] = new PdfPCell(paragraph21);//单元格内容
        body2[12] = new PdfPCell(paragraph22);//单元格内容
        body2[13] = new PdfPCell(paragraph23);//单元格内容
        body2[1].setColspan(11);
        body2[13].setColspan(2);
        body2[0].setHorizontalAlignment(Element.ALIGN_CENTER);
        body2[1].setHorizontalAlignment(Element.ALIGN_LEFT);
        body2[12].setHorizontalAlignment(Element.ALIGN_CENTER);
        body2[13].setHorizontalAlignment(Element.ALIGN_LEFT);
        body2[0].setVerticalAlignment(Element.ALIGN_MIDDLE);
        body2[1].setVerticalAlignment(Element.ALIGN_MIDDLE);
        body2[12].setVerticalAlignment(Element.ALIGN_MIDDLE);
        body2[13].setVerticalAlignment(Element.ALIGN_MIDDLE);
        body2[0].setMinimumHeight(15);
        body2[1].setMinimumHeight(15);
        body2[12].setMinimumHeight(15);
        body2[13].setMinimumHeight(15);
        PdfPRow rowBody2 = new PdfPRow(body2);

        PdfPCell body3[] = new PdfPCell[tableBodyFlag];
        Paragraph paragraph30 = new Paragraph("账号", fontValueBody);
        Paragraph paragraph31 = new Paragraph("账号", fontValueBody);
        Paragraph paragraph32 = new Paragraph("起息日期", fontValueBody);
        Paragraph paragraph33 = new Paragraph("起息日期", fontValueBody);
        body3[0] = new PdfPCell(paragraph30);//单元格内容
        body3[1] = new PdfPCell(paragraph31);//单元格内容
        body3[12] = new PdfPCell(paragraph32);//单元格内容
        body3[13] = new PdfPCell(paragraph33);//单元格内容
        body3[1].setColspan(11);
        body3[13].setColspan(2);
        body3[0].setHorizontalAlignment(Element.ALIGN_CENTER);
        body3[1].setHorizontalAlignment(Element.ALIGN_LEFT);
        body3[12].setHorizontalAlignment(Element.ALIGN_CENTER);
        body3[13].setHorizontalAlignment(Element.ALIGN_LEFT);
        body3[0].setVerticalAlignment(Element.ALIGN_MIDDLE);
        body3[1].setVerticalAlignment(Element.ALIGN_MIDDLE);
        body3[12].setVerticalAlignment(Element.ALIGN_MIDDLE);
        body3[13].setVerticalAlignment(Element.ALIGN_MIDDLE);
        body3[0].setMinimumHeight(15);
        body3[1].setMinimumHeight(15);
        body3[12].setMinimumHeight(15);
        body3[13].setMinimumHeight(15);
        PdfPRow rowBody3 = new PdfPRow(body3);

        PdfPCell body4[] = new PdfPCell[tableBodyFlag];
        Paragraph paragraph40 = new Paragraph("种类", fontValueBody);
        Paragraph paragraph41 = new Paragraph("种类".toString(), fontValueBody);
        Paragraph paragraph42 = new Paragraph("利率", fontValueBody);
        Paragraph paragraph43 = new Paragraph("".toString(), fontValueBody);
        Paragraph paragraph44 = new Paragraph("约转方式", fontValueBody);
        Paragraph paragraph45 = new Paragraph("约转方式".toString(), fontValueBody);
        Paragraph paragraph46 = new Paragraph("约转存期", fontValueBody);
        Paragraph paragraph47 = new Paragraph("约转存期".toString(), fontValueBody);
        Paragraph paragraph48 = new Paragraph("存期", fontValueBody);
        Paragraph paragraph49 = new Paragraph("存期".toString(), fontValueBody);
        body4[0] = new PdfPCell(paragraph40);//单元格内容
        body4[1] = new PdfPCell(paragraph41);//单元格内容
        body4[3] = new PdfPCell(paragraph42);//单元格内容
        body4[4] = new PdfPCell(paragraph43);//单元格内容
        body4[6] = new PdfPCell(paragraph44);//单元格内容
        body4[7] = new PdfPCell(paragraph45);//单元格内容
        body4[9] = new PdfPCell(paragraph46);//单元格内容
        body4[10] = new PdfPCell(paragraph47);//单元格内容
        body4[12] = new PdfPCell(paragraph48);//单元格内容
        body4[13] = new PdfPCell(paragraph49);//单元格内容
        body4[1].setColspan(2);
        body4[4].setColspan(2);
        body4[7].setColspan(2);
        body4[10].setColspan(2);
        body4[13].setColspan(2);
        body4[0].setHorizontalAlignment(Element.ALIGN_CENTER);
        body4[1].setHorizontalAlignment(Element.ALIGN_LEFT);
        body4[3].setHorizontalAlignment(Element.ALIGN_CENTER);
        body4[4].setHorizontalAlignment(Element.ALIGN_LEFT);
        body4[6].setHorizontalAlignment(Element.ALIGN_CENTER);
        body4[7].setHorizontalAlignment(Element.ALIGN_LEFT);
        body4[9].setHorizontalAlignment(Element.ALIGN_CENTER);
        body4[10].setHorizontalAlignment(Element.ALIGN_LEFT);
        body4[12].setHorizontalAlignment(Element.ALIGN_CENTER);
        body4[13].setHorizontalAlignment(Element.ALIGN_LEFT);


        body4[0].setVerticalAlignment(Element.ALIGN_MIDDLE);
        body4[1].setVerticalAlignment(Element.ALIGN_MIDDLE);
        body4[3].setVerticalAlignment(Element.ALIGN_MIDDLE);
        body4[4].setVerticalAlignment(Element.ALIGN_MIDDLE);
        body4[6].setVerticalAlignment(Element.ALIGN_MIDDLE);
        body4[7].setVerticalAlignment(Element.ALIGN_MIDDLE);
        body4[9].setVerticalAlignment(Element.ALIGN_MIDDLE);
        body4[10].setVerticalAlignment(Element.ALIGN_MIDDLE);
        body4[12].setVerticalAlignment(Element.ALIGN_MIDDLE);
        body4[13].setVerticalAlignment(Element.ALIGN_MIDDLE);

        body4[0].setMinimumHeight(15);
        body4[1].setMinimumHeight(15);
        body4[3].setMinimumHeight(15);
        body4[4].setMinimumHeight(15);
        body4[6].setMinimumHeight(15);
        body4[7].setMinimumHeight(15);
        body4[9].setMinimumHeight(15);
        body4[10].setMinimumHeight(15);
        body4[12].setMinimumHeight(15);
        body4[13].setMinimumHeight(15);

        PdfPRow rowBody4 = new PdfPRow(body4);


        PdfPCell body5[] = new PdfPCell[tableBodyFlag];
        Paragraph paragraph50 = new Paragraph("开户银行", fontValueBody);
        Paragraph paragraph51 = new Paragraph("开户银行", fontValueBody);
        Paragraph paragraph52 = new Paragraph("到期日期", fontValueBody);
        Paragraph paragraph53 = new Paragraph("到期日期", fontValueBody);
        body5[0] = new PdfPCell(paragraph50);//单元格内容
        body5[1] = new PdfPCell(paragraph51);//单元格内容
        body5[12] = new PdfPCell(paragraph52);//单元格内容
        body5[13] = new PdfPCell(paragraph53);//单元格内容
        body5[1].setColspan(11);
        body5[13].setColspan(2);
        body5[0].setHorizontalAlignment(Element.ALIGN_CENTER);
        body5[1].setHorizontalAlignment(Element.ALIGN_LEFT);
        body5[12].setHorizontalAlignment(Element.ALIGN_CENTER);
        body5[13].setHorizontalAlignment(Element.ALIGN_LEFT);
        body5[0].setVerticalAlignment(Element.ALIGN_MIDDLE);
        body5[1].setVerticalAlignment(Element.ALIGN_MIDDLE);
        body5[12].setVerticalAlignment(Element.ALIGN_MIDDLE);
        body5[13].setVerticalAlignment(Element.ALIGN_MIDDLE);
        body5[0].setMinimumHeight(15);
        body5[1].setMinimumHeight(15);
        body5[12].setMinimumHeight(15);
        body5[13].setMinimumHeight(15);
        PdfPRow rowBody5 = new PdfPRow(body5);

        PdfPCell body6[] = new PdfPCell[tableBodyFlag];
        Paragraph paragraph60 = new Paragraph("金额(大写)", fontValueBody);
        Paragraph paragraph61 = new Paragraph("金额(大写)".toString(), fontValueBody);
        body6[0] = new PdfPCell(paragraph60);//单元格内容
        body6[1] = new PdfPCell(paragraph61);//单元格内容
        body6[1].setColspan(14);
        body6[0].setHorizontalAlignment(Element.ALIGN_CENTER);
        body6[1].setHorizontalAlignment(Element.ALIGN_LEFT);
        body6[0].setVerticalAlignment(Element.ALIGN_MIDDLE);
        body6[1].setVerticalAlignment(Element.ALIGN_MIDDLE);
        body6[0].setMinimumHeight(15);
        body6[1].setMinimumHeight(15);
        PdfPRow rowBody6 = new PdfPRow(body6);

        PdfPCell body7[] = new PdfPCell[tableBodyFlag];
        Paragraph paragraph70 = new Paragraph("本电子凭证所示存单信息,仅对借款人作为质押贷款之用,存款人不得提前支取。", fontValueBody);

        body7[0] = new PdfPCell(paragraph70);//单元格内容
        body7[0].setColspan(15);
        body7[0].setVerticalAlignment(Element.ALIGN_MIDDLE);
        body7[0].setMinimumHeight(20);
        PdfPRow rowBody7 = new PdfPRow(body7);


        listRowBody.add(rowBody1);
        listRowBody.add(rowBody2);
        listRowBody.add(rowBody3);
        listRowBody.add(rowBody4);
        listRowBody.add(rowBody5);
        listRowBody.add(rowBody6);
        listRowBody.add(rowBody7);


        document.add(tableBody);
    }
}

结果

一页1条:

一页2条:

一页4条:

总结

关于pdf一页多条的需求,是我近期在实际开发中遇到的,当时没有接触过POI这块,后来也是分析和学习,查阅了很多资料搜寻到的,希望对各位正在遇到的该问题的有帮助,谢谢各位!

注意

需求中,有可能一页A4装不下3条或者4条,甚至2条就不行,这时候需要去和产品沟通,是否需要调整需求。比如A4需要查询几个班的成绩单,一个班的数据可能一张A4展示不下,这是有可能舍弃一页多条的需求。

标签:java,ALIGN,Element,Paragraph,PdfPCell,new,100w,pdf,body4
From: https://blog.csdn.net/Wjingze/article/details/139703501

相关文章

  • java设计模式之-工厂模式
    工厂模式是一种创建对象的设计模式,它通过将对象的实例化过程封装在一个工厂类中,从而实现对象的创建和使用的解耦。它属于创建型模式的一种,可以帮助我们更加灵活地创建对象。工厂模式主要解决的问题是在对象的创建过程中,如果直接在代码中使用new关键字来创建对象,会导致代码的耦合......
  • Java——变量作用域和生命周期
    一、作用域1、作用域简介在Java中,作用域(Scope)指的是变量、方法和类在代码中的可见性和生命周期。理解作用域有助于编写更清晰、更高效的代码。2、作用域块作用域(BlockScope):块作用域是指在大括号{}内定义的变量的作用域。变量只在其定义的块内可见和有效,包括循环、条件......
  • java1
    在继承中,创建子类对象,访问成员方法的规则: 创建的对象是谁,就优先用谁,没有再向上找 注意:无论是成员变量还是成员方法, 如果没有都是向上找父类,不会向下找子类继承的特点:子类可以拥有父类的内容,此处子类还可以拥有自己独有的内容(成员变量和方法) 定义继承的格式:(至少需要......
  • 第六站:Java橙——JavaFX的动感舞台
    JavaFX入门案例:创建一个基础UI应用JavaFX允许开发者使用Java语言来设计和实现富客户端应用程序,这些应用程序具有高度互动的用户界面(UI),支持2D和3D图形,以及媒体播放等特性。下面,我们将通过一个简单的案例来展示如何使用JavaFX创建一个基本的UI应用,包括UI设计、构建场景图、......
  • 认识 Java 里的线程和方法
    Thread和Runnable的区别Thread才是Java里对线程的唯一抽象,Runnable只是对任务(业务逻辑)的抽象。Thread可以接受任意一个Runnable的实例并执行启动线程的方式有:1、XextendsThread;,然后X.start2、XimplementsRunnable;然后交给Thread运行永远都只有thread.star......
  • Linux下Java环境安装
    Linux下open-jdk1.8安装教程一.下载安装包Javadownload下载后上传到服务器二.安装1.解压安装包tar-zxvfjdk-8u341-linux-x64.tar.gz2.配置环境变量在/etc/profile文件中,新增Java的环境变量vi/etc/profileexportJAVA_HOME=/usr/local/jdk/jdk1.8.0_341export......
  • Java接口的介绍与使用,多态的介绍与使用
    第一章.接口1.接口的介绍2.接口的定义以及使用1.接口:是一个引用数据类型,是一种标准,规则2.关键字:a.interface接口publicinterface接口名{}b.implements实现实现类implements接口名{}3.接口中可以定义的成员:a.jdk7以及之......
  • PDF转换成JPEG格式
     使用NuGet程序包下载安装 O2S.Components.PDFRender4NET.dll usingO2S.Components.PDFRender4NET;//引用 O2S.Components.PDFRender4NET.dll  ///<summary>///PDF转JPEG///</summary>///<paramname="pdfInputPath&q......
  • Java习题
    1.题目使用Java的输入、输出流将一个文本文件的内容按行读出,每读出一行就顺序添加行号,并写入到另一个文件中。代码及详细注释importjava.io.*;//导入JavaI/O库中的所有类publicclassE{//定义一个公共类Epublicstaticvoidmain(Stringargs[]){//主......
  • Java Mail报错:javax 迁移到 jakarta
    javax(JavaExtension)作为包名,包含了一系列的Java扩展包,提供了各种不同的功能,例如servlet、JDBC、JMS等。2017年,Oracle将JavaEE技术移交给EclipseFoundation,这个项目随后被重命名为JakartaEE。在这个过渡过程中,EclipseFoundation决定将所有JavaEEAPI从java......