使用itext生成PDF表格报表

发布时间 2023-07-26 09:44:15作者: 行人~

使用iText生成PDF表格形式报表

1、引用JAR包

<dependency>
  <groupId>com.itextpdf</groupId>
  <artifactId>itextpdf</artifactId>
  <version>5.5.13.3</version>
</dependency>

 itext5是开源的,可以免费使用

2、开始创建PDF

package com.example.pdf.demo;

import com.itextpdf.text.*;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class PdfCreateUtil {
    //文件路径
    private static String filePath = "D:\\测试文档.pdf";
    //字体文件路径
    private static String fontPath = "C:\\Windows\\Fonts\\simhei.ttf";
    public static void  createPdf() throws IOException, DocumentException {
        //创建文档对象设置文档大小
        Document document = new Document(PageSize.A4);
        File file = new File(filePath);
        FileOutputStream fos = new FileOutputStream(file);
        PdfWriter writer = PdfWriter.getInstance(document, fos);
        // 如果直接需要输出到返回流中可以使用一下代码
        // HttpServletResponse res = null; 请求的返回体
        // PdfWriter.getInstance(document,res.getOutputStream());
        //字体
        BaseFont font = BaseFont.createFont(fontPath, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
        //添加页码
        addFooter(font,12,PageSize.A4,writer);
        document.open();

        //标题字体
        Font titleFont = new Font(font, 12, Font.BOLD);
        //设置每一列宽度
        float[] widths = {50f, 50f, 50f, 50f};
        //创建一个表格对象
        PdfPTable pdfPTable = new PdfPTable(widths);
        PdfPCell pdfPCell = null;
        for (int i = 0; i < 4; i++) {
            pdfPCell = new PdfPCell(new Paragraph("表头1", titleFont));
            //表格内容居中
            pdfPCell.setHorizontalAlignment(Element.ALIGN_CENTER);
            pdfPTable.addCell(pdfPCell);
        }
        for (int i = 0; i < 20; i++) {
            pdfPCell = new PdfPCell(new Paragraph(i + "", titleFont));
            //表格内容居中
            pdfPCell.setHorizontalAlignment(Element.ALIGN_CENTER);
            pdfPTable.addCell(pdfPCell);
        }
        document.add(pdfPTable);
        document.close();
    }

    public static void addFooter(BaseFont font,int fontSize,Rectangle pageSize,PdfWriter writer){
        ItextPdfHeaderFooter itextPdfHeaderFooter = new ItextPdfHeaderFooter(font,fontSize,pageSize);
        writer.setPageEvent(itextPdfHeaderFooter);
    }
    public static void main(String[] args) throws IOException, DocumentException {
        createPdf();
    }
}

3、页码生成监听器

package com.example.pdf.demo;

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

public class ItextPdfHeaderFooter extends PdfPageEventHelper {
    /**
     * 页眉
     */
    public String header ="";
    /**
     * 文档字体大小
     */
    public int persentFontSize = 12;

    public Rectangle pageSize = PageSize.A4;

    public PdfTemplate total;

    public BaseFont bf = null;

    public Font fontDetail = null;

    public ItextPdfHeaderFooter() {
    }

    public ItextPdfHeaderFooter(BaseFont bf,int persentFontSize, Rectangle pageSize) {
        this.persentFontSize = persentFontSize;
        this.pageSize = pageSize;
        this.bf = bf;
    }

    public ItextPdfHeaderFooter(String header, int persentFontSize, Rectangle pageSize) {
        this.header = header;
        this.persentFontSize = persentFontSize;
        this.pageSize = pageSize;
    }

    public void setHeader(String header) {
        this.header = header;
    }

    public void setPersentFontSize(int persentFontSize) {
        this.persentFontSize = persentFontSize;
    }

    @Override
    public void onOpenDocument(PdfWriter writer, Document document) {
        total = writer.getDirectContent().createTemplate(60,60);
    }

    /**
     * 写入页脚
     * @param writer
     * @param document
     */
    @Override
    public void onEndPage(PdfWriter writer, Document document) {
        //如果有封面第一页跳过,后续计算页码需要减去封面页数
//        if(writer.getPageNumber()==1)
//        {
//            return;
//        }
        try{
            if(fontDetail==null){
                fontDetail = new Font(bf,persentFontSize, Font.NORMAL);
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        //1、写入页脚
        ColumnText.showTextAligned(writer.getDirectContent(), Element.ALIGN_LEFT,new Phrase(header,fontDetail),document.left(),document.top()+20,0);

        //有封面减去封面页数
        //        int pages = writer.getPageNumber()-1;
        int pages = writer.getPageNumber();
        String foot = "第"+pages+"页/共";
        Phrase footer = new Phrase(foot,fontDetail);

        //计算长度位置
        float len = bf.getWidthPoint(foot, persentFontSize);

        PdfContentByte cb = writer.getDirectContent();

        ColumnText.showTextAligned(cb,Element.ALIGN_CENTER,footer,(document.rightMargin()+document.right()+document.leftMargin()-document.left()-len)/2.0F+20F,document.bottom()-20,0);
        cb.addTemplate(total,(document.rightMargin()+document.right()+document.leftMargin()-document.left())/2.0F+20F,document.bottom()-20);
    }

    /**
     * 关闭文档时添加总页码
     * @param writer
     * @param document
     */
    @Override
    public void onCloseDocument(PdfWriter writer, Document document) {
        if(writer.getPageNumber()==1)
        {
            return;
        }
        total.beginText();
        total.setFontAndSize(bf,persentFontSize);
        //有封面减去封面页数
        //        String footT = "" + (writer.getPageNumber()-1)+"页";
        String footT = "" + (writer.getPageNumber())+"页";
        Phrase footer = new Phrase(footT,fontDetail);
        total.showText(footer.getContent());
        total.endText();
        total.closePath();
    }
}

4、最终实现效果如下