首页 > 编程语言 >JAVA开发 PDF文件生成表格,表格根据内容自动调整高度

JAVA开发 PDF文件生成表格,表格根据内容自动调整高度

时间:2024-06-11 21:58:56浏览次数:24  
标签:JAVA String 表格 int sum float new PDF contentStream

1、展示效果

在这里插入图片描述
在这里插入图片描述

2、相关功能实现

JAVA开发 使用Apache PDFBox库生成PDF文件,绘制表格

3、实现代码

import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.font.PDType0Font;
import org.apache.pdfbox.pdmodel.font.PDType1Font;

import java.io.File;
import java.io.IOException;

import java.text.SimpleDateFormat;
import java.util.Date;

public class TableInPDFBox {

     private static final int WARPNUM  = 11;   //每行显示的字符数量,一个中文占一个字符,其他字符占0.5个

    //判断输入的字符是不是中文
    public static boolean isChineseChar(char ch) {
        String regex = "[\u4E00-\u9FA5]";
        String charToCheck = String.valueOf(ch);
        return charToCheck.matches(regex);
    }

    //每行显示的字符数量,获取每个字符串所需要的行数
    public static  int GetWarpRowByString(String str){
        float sum = 0 ;   //sum 用来计算中文字符
        int row = 0,index=0;
        char[] tempArr = str.toCharArray();
        for(int i = 0;i<tempArr.length;i++){
            if(isChineseChar(tempArr[i])){
                sum +=1;
            }else{
                sum +=0.5f;
            }
            if(sum == WARPNUM){
                row++;
                sum=0;
            }else if(sum>WARPNUM){
                i--;
                row++;
                sum = 0;
            }else{

            }
        }
        row = row +1;
        return row;
    }

    //根据每行的内容,获取最大需要换行的行数(只比较爱好、优势两列)
    public static int[] ConfirmRowLength(String[][] stu,int index){
        int[] MaxlengthArr = new int[stu.length];
        MaxlengthArr[0] = 1;
        for(int i = 1;i<stu.length;i++){
            int max = GetWarpRowByString(stu[i][0]);
            for(int j=index;j<stu[i].length;j++){
                int strRow = GetWarpRowByString(stu[i][j]);
                if(strRow>max){
                    max = strRow;
                }
            }
            MaxlengthArr[i] = max;
        }
        return MaxlengthArr;
    }

    //将字符串按照最大每行显示数进行分割,保存到字符串数组中
    public static String[] GetWarpStr(int rowLength,String str){
        float sum = 0.0f;
        String[] returnStr=new String[rowLength];
        int returnIndex = 0;
        String temp="";
        char[] strArr = str.toCharArray();
        for(int i= 0;i<strArr.length;i++){
            if(isChineseChar(strArr[i])){
                sum = sum + 1.0f;
            }else{
                sum+=0.5f;
            }
            temp = temp + strArr[i];
            if(sum == WARPNUM){
                returnStr[returnIndex++]= temp;
                temp = "";
                sum = 0.0f;
            }else if(sum >= WARPNUM){
                returnStr[returnIndex++]= temp.substring(0,temp.length()-1);
                i--;
                temp = "";
                sum = 0.0f;
            }else{

            }
        }
        if(!temp.isEmpty() && returnIndex<rowLength){
            returnStr[returnIndex++] = temp;
        }
        return returnStr;
    }


    public static void main(String[] args) {
        PDDocument document = null;
        String[][] stuData = new String[][]{{"姓名","工号","部门","爱好","优势"}
                ,{"张三丰","WD0001","武当派","阅读让我们获得知识和灵感,运动可以让我们保持身体健康。阅读让我们获得知识和灵感,运动可以让我们保持身体健康。阅读让我们获得知识和灵感,运动可以让我们保持身体健康。阅读让我们获得知识和灵感,运动可以让我们保持身体健康。","武当派和三丰派的祖师,会少林武功和九阳真经,武功特点是阴阳互融、刚柔并济,达到了武学的巅峰。真是泰裤辣。武功特点是阴阳互融、刚柔并济,达到了武学的巅峰。真是泰裤辣"}
                ,{"郭  襄","EM0001","峨嵋派","书法有助于修养身心,陶冶情操,既练习了字,也可以修炼沉稳的性格.书法有助于修养身心,陶冶情操,既练习了字,也可以修炼沉稳的性格。","会峨眉九阳功,擅长黄药师最精妙的剑法之一的落英剑法。"}};
        try {
            int[] lengthArr = ConfirmRowLength(stuData,3);
            float[] rowIndxArr = new float[stuData.length+1];
            float[] colIndxArr = new float[stuData[0].length+1];
            document = new PDDocument();
            PDPage page = new PDPage();
            document.addPage(page);

            PDPageContentStream contentStream = new PDPageContentStream(document, page);

            Date date = new Date();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd HHmmss");
            String dateFormat = sdf.format(date);

            // 表格参数
            int rows = 3;
            int cols = 5;
            float cellWidth1 = 60 , cellWidth2 = 150;
            float cellHeight = 30;
            float xStart = 30,xEnd = xStart + 3 * cellWidth1+2*cellWidth2;       //横向开始线的x点,横向结束线的x点
            float yStart = 700,yEnd = 0;   //纵向开始线的y点,纵向结束线的y点


            float sumRows = cellHeight;
            // 绘制表格x轴线
            for (int i = 0; i <= rows; i++) {
                float rowY =0;
                if(i == 0){
                    rowY = yStart - i * cellHeight;
                }else{
                    sumRows =  sumRows +lengthArr[i-1]*10+5*2;
                    rowY = yStart - sumRows;
                    yEnd = rowY;
                }
                rowIndxArr[i] = rowY;
                contentStream.moveTo(xStart, rowY);
                contentStream.lineTo(xEnd, rowY);
                contentStream.stroke();
            }

            //绘制表格y轴线
            for (int j = 0; j <= cols; j++) {
                float colX;
                if(j<=3){
                    colX= xStart + j * cellWidth1;
                }else{
                    colX = xStart +3*cellWidth1 +(j-3)*cellWidth2;
                }
                colIndxArr[j] = colX;
                contentStream.moveTo(colX, yStart);
                contentStream.lineTo(colX, yEnd);
                contentStream.stroke();
            }

            // 填写表格内容
            File fontFile = new File("C:\\Windows\\Fonts\\SIMLI.TTF"); // 字体文件路径
            PDType0Font font = PDType0Font.load(document, fontFile);
            for (int i = 0; i < rows; i++) {
                for (int j = 0; j < cols; j++) {
                    String text = stuData[i][j];
                    String[] rowText = GetWarpStr(lengthArr[i],text);
                    for(int k = 0;k<rowText.length && rowText[k]!=null;k++){
                        contentStream.beginText();
                        contentStream.setFont(font, 12);
                        contentStream.newLineAtOffset(colIndxArr[j]+5, rowIndxArr[i]-10-10*k);
                        contentStream.showText(rowText[k]);
                        contentStream.endText();
                    }
                }
            }

            contentStream.close(); // 关闭内容流

            // 保存PDF
            document.save("D:\\JAVAFILE\\attachments\\pdfs\\" + dateFormat + "  table.pdf");

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (document != null) {
                try {
                    document.close(); // 关闭文档
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

标签:JAVA,String,表格,int,sum,float,new,PDF,contentStream
From: https://blog.csdn.net/a_waste_only/article/details/139609582

相关文章

  • 2024最强Java面试八股
    Java基础八股文(背诵版)Java语言具有哪些特点?Java为纯面向对象的语言。它能够直接反应现实生活中的对象。具有平台无关性。Java利用Java虚拟机运行字节码,无论是在Windows、Linux还是MacOS等其它平台对Java程序进行编译,编译后的程序可在其它平台运行。Java为解释型......
  • 使用 Flink SQL 读取本地csv文件(Java实现)
    data.csv内容:1,Tom,152,Lily,133,Mike,214,John,205,Emma,186,Sophia,197,David,228,James,169,Olivia,1710,Robert,2311,Emily,1412,Daniel,2513,Amelia,24代码:packagecom.auguigu.demo;importorg.apache.flink.streaming.api.datastream.DataStream;impo......
  • 线程介绍及其Java如何用Thread 类创建线程和操作线程方法
    目录一、进程和线程1.1进程特征2.2线程特征2.3区别二、利用Thread类创建线程2.1通过创建Thread子类,重写run()方法2.2通过实现Runnable接口,重写run()方法2.3.Callable接口+FutureTask创建线程2.3三种方法区别1.通过创建Thread子类,重写run()方法2.通过实......
  • 基本数据类型 String,null 和 undefined,运算符,流程控制,JavaScript之数组,数组常用
    Ⅰ基本数据类型String【一】String类型String类型就是字符串类型【二】定义变量【1】常规变量var变量名="变量值";//一般用这种var变量名='变量值';不支持三引号【2】可以先声明不赋值先用varb;再对变量b赋值varb='6';【三】字符串的格式化输出语法......
  • 神奇的JavaScript弱等价类型转换
    JavaScript语言特性-类型转换JavaScript这门语言的类型系统从来没有它表面看起来的那样和善,虽然比起Java、C#等一众强类型语言,它的弱类型使用起来似乎是如此便利,但正因为它极高的自由度,所以才会衍生出令人摸不着头脑的荒诞行为。举个例子,虽然我们都知道一个包含内容的字符串会......
  • 探索Java的奥秘:网络编程、反射与注解的深度解析
    Java,作为一门功能强大的编程语言,在网络编程、反射和注解方面提供了丰富的支持和灵活的应用。本文将深入探讨这些概念,并通过实际例子来加深理解。一、Java网络编程1.1网络编程基础网络编程是Java语言的一大亮点,它允许我们创建能够通过网络进行通信的程序。Java提供了java......
  • 大学生HTML期末大作业——HTML+CSS+JavaScript美食网站(零食)
    HTML+CSS+JS【美食网站】网页设计期末课程大作业web前端开发技术web课程设计网页规划与设计......
  • 大学生HTML期末大作业——HTML+CSS+JavaScript购物商城(华为手机)
    HTML+CSS+JS【购物商城】网页设计期末课程大作业web前端开发技术web课程设计网页规划与设计......
  • Java中List集合中多个字段如何排序
    开源项目SDK:https://github.com/mingyang66/spring-parent个人文档:https://mingyang66.github.io/raccoon-docs/#/一、首先定义一个三个属性的People类publicclassPeople{privateStringname;privateintage;privateintheight;publicPeople......
  • 【数据库】mybatis生成java代码之AutoGenerator配置
    哈喽,大家好,我是木头左,AI改变生活!本文将详细解释MyBatis生成Java代码的过程,包括全局配置、数据源配置和策略配置。1.全局配置首先,我们需要创建一个GlobalConfig对象,用于配置MyBatis的全局设置。以下是一些常用的全局配置选项:setOutputDir(StringoutputDir):设置生......