openPDF创建pdf工具类

该代码片段展示了如何使用Java的openpdf库创建PDF文件中的表格、段落和单元格。提供了不同格式的单元格创建方法,包括设置文字、字体、背景色、对齐方式以及行和列的合并。此外,还包括页头和页脚的设置以及时间戳的添加。
摘要由CSDN通过智能技术生成

大多是pdf都是以表格的,PDFPTable, Paragraph段落使用

         <dependency>
                <groupId>com.github.librepdf</groupId>
                <artifactId>openpdf</artifactId>
                <version>1.3.26</version>
            </dependency>
import com.lowagie.text.*;
import com.lowagie.text.Font;
import com.lowagie.text.Image;
import com.lowagie.text.Rectangle;
import com.lowagie.text.pdf.*;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;

import java.awt.*;
import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

/**
 * pdf工具
 *
 * @author weepal
 * @date 2022/11/29
 */
public class PDFUtils {


    /**
     * 创建一个pdfcell,默认的格式是,<br/> 水平居中,白色背景,12号字体,
     * @param content
     * @return
     * @throws IOException
     * @throws DocumentException
     */
    public static PdfPCell createCell(String content ) throws IOException, DocumentException {
        content = StringUtils.isEmpty(content) ? " " : content;
        PdfPCell cell = new PdfPCell();
        cell.setVerticalAlignment(Element.ALIGN_CENTER);
        cell.setHorizontalAlignment(Element.ALIGN_CENTER);
        cell.setPhrase(new Phrase(content, getFont()));
        return cell;
    }

    /**
     * 创建一个pdfcell,默认的格式是,<br/> 水平居中,白色背景,12号字体,
     * @param content
     * @return
     * @throws IOException
     * @throws DocumentException
     */
    public static PdfPCell createCell(String content,int rowspan,int colspan  ,int verticalAlignment,int horizontalAlignment ) throws IOException, DocumentException {
        content = StringUtils.isEmpty(content) ? " " : content;
        PdfPCell cell = new PdfPCell();
        cell.setVerticalAlignment(verticalAlignment);
        cell.setHorizontalAlignment(horizontalAlignment);
        cell.setRowspan(rowspan);
        cell.setColspan(colspan);
        cell.setPhrase(new Phrase(content, getFont()));
        return cell;
    }


    /**
     * 创建一个pdfcell,默认的格式是,<br/> 水平居中,白色背景,12号字体,
     * @param content
     * @return
     * @throws IOException
     * @throws DocumentException
     */
    public static PdfPCell createCell(String content,int rowspan,int colspan ) throws IOException, DocumentException {
        content = StringUtils.isEmpty(content) ? " " : content;
        PdfPCell cell = new PdfPCell();
        cell.setVerticalAlignment(Element.ALIGN_CENTER);
        cell.setHorizontalAlignment(Element.ALIGN_CENTER);
        cell.setRowspan(rowspan);
        cell.setColspan(colspan);
        cell.setPhrase(new Phrase(content, getFont()));
        return cell;
    }

        /**
     * 创建一个pdfcell,默认的格式是,<br/> 水平居中,白色背景,12号字体,
     * @param content
     * @return
     * @throws IOException
     * @throws DocumentException
     */
    public static PdfPCell createCell(String content,int rowspan,int colspan,Font font ) throws IOException, DocumentException {
        content = StringUtils.isEmpty(content) ? " " : content;
        PdfPCell cell = new PdfPCell();
        cell.setVerticalAlignment(Element.ALIGN_CENTER);
        cell.setHorizontalAlignment(Element.ALIGN_CENTER);
        cell.setRowspan(rowspan);
        cell.setColspan(colspan);
        cell.setPhrase(new Phrase(content, font));
        return cell;
    }


    /**
     * 创建一个pdfcell, 设置背景色
     * @param content
     * @return
     * @throws IOException
     * @throws DocumentException
     */
    public static PdfPCell createCell(String content, Color bgColor  ) throws IOException, DocumentException {
        content = StringUtils.isEmpty(content) ? " " : content;
        PdfPCell cell = new PdfPCell();
        cell.setVerticalAlignment(Element.ALIGN_CENTER);
        cell.setHorizontalAlignment(Element.ALIGN_CENTER);
        cell.setBackgroundColor(bgColor);
        cell.setPhrase(new Phrase(content, getFont()));
        return cell;
    }

    /**
     * 创建一个pdfcell, 设置背景色
     * @param content
     * @return
     * @throws IOException
     * @throws DocumentException
     */
    public static PdfPCell createCell(String content,Font font  ) throws IOException, DocumentException {
        content = StringUtils.isEmpty(content) ? " " : content;
        PdfPCell cell = new PdfPCell();
        cell.setPhrase(new Phrase(content, font));
        return cell;
    }




    /**
     * 设置页头时间样式,需要在打开文档之前进行设置
     * @return
     * @throws IOException
     * @throws DocumentException
     */
    public static HeaderFooter setHeader() throws IOException, DocumentException {

        Font font=getFont(10,Font.NORMAL);
        HeaderFooter header =new HeaderFooter(new Phrase(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")),font),false);
        header.setBorder(0);
        header.setAlignment(Element.ALIGN_LEFT);
        return header;
    }


    /**
     * 设置页脚,需要在打开文档之前进行设置
     * @return   -xxx-
     * @throws IOException
     * @throws DocumentException
     */
    public static HeaderFooter setFooter() throws IOException, DocumentException {
        Font font=getFont(10,Font.NORMAL);
        Phrase phrase1 = new Phrase("-", font);
        Phrase phrase2 = new Phrase("-", font);
        HeaderFooter footer =new HeaderFooter(phrase1,phrase2);
        footer.setBorder(0);
        footer.setAlignment(Element.ALIGN_CENTER);
        return footer;
    }









    /**
     * 标题
     * @param content
     * @return
     * @throws IOException
     * @throws DocumentException
     */
    public static Paragraph createTitle(String content,int fontSize,Color fontColor) throws IOException, DocumentException {
        Font font = getFont(fontSize, Font.BOLD);
        font.setColor(fontColor);
        Paragraph paragraph = new Paragraph(content, font);
        paragraph.setAlignment(Element.ALIGN_CENTER);
        return paragraph;
    }


    /**
     * 标题
     * @param content
     * @return
     * @throws IOException
     * @throws DocumentException
     */
    public static Paragraph createTitle(String content,Color fontColor) throws IOException, DocumentException {
        Font font = getFont(24, Font.BOLD);
        font.setColor(fontColor);
        Paragraph paragraph = new Paragraph(content, font);
        paragraph.setAlignment(Element.ALIGN_CENTER);
        return paragraph;
    }





    /**
     * 普通文本段落
     *
     * @param content
     * @return
     * @throws IOException
     * @throws DocumentException
     */
    public static Paragraph createParagraph(String content) throws IOException, DocumentException {
        content=StringUtils.isEmpty(content)?" ":content;
        Paragraph paragraph = new Paragraph(content, getFont());
        paragraph.setAlignment(Element.ALIGN_LEFT);
        paragraph.setIndentationLeft(12); //设置左缩进
        paragraph.setIndentationRight(12); //设置右缩进
        paragraph.setFirstLineIndent(24); //设置首行缩进
        paragraph.setLeading(20f); //行间距
        paragraph.setSpacingBefore(5f); //设置段落上空白
        paragraph.setSpacingAfter(10f); //设置段落下空白
        return paragraph;
    }


    /**
     * 获取图片对象
     * @param imageByte
     */
    public static PdfPCell createImage( byte[] imageByte ) throws IOException {
        Image instance = Image.getInstance(imageByte);
        PdfPCell imageCell=new PdfPCell();
        imageCell.setImage(instance);
        return imageCell;
    }

    /**
     * 获取图片对象
     * @param inputStream
     */
    public static PdfPCell createImage(InputStream inputStream) throws IOException {
        Image instance = Image.getInstance(IOUtils.toByteArray(inputStream));
        PdfPCell imageCell=new PdfPCell();
        imageCell.setImage(instance);
        return imageCell;
    }

    /**
     * 获取图片对象
     * @param image
     */
    public static PdfPCell createImage(Image image) throws IOException {
        Image instance = Image.getInstance(image);
        PdfPCell imageCell=new PdfPCell();
        imageCell.setImage(instance);
        return imageCell;
    }


    /**
     * 字体
     */
    public static Font getFont() throws IOException, DocumentException {
        BaseFont baseFont = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
        Font font=new Font(baseFont,10,Font.NORMAL);
        return font;
    }

    /**
     * 字体
     */
    public static Font getFont(int fontSize,int fontStyle) throws IOException, DocumentException {
        BaseFont baseFont = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
        Font font=new Font(baseFont,fontSize,fontStyle);
        return font;
    }



    /**
     * 页脚页数显示
     * @return
     */
    public static PdfPageEventHelper pdfPageEventHelper(){
        return new PdfPageEventHelperBuilder();
    }

    /**
     * 清除table的边框。
     * @param pdfPTable
     */
    public static void clearTableBorder(PdfPTable pdfPTable){
        pdfPTable.getRows().forEach(x->{
            for (PdfPCell cell : x.getCells()) {
                if(ObjectUtils.isNotEmpty(cell)){
                    cell.setBorder(0);
                }
            }
        });
    }
    public static void clearTableBorderTopAndBotton(PdfPTable pdfPTable){
        pdfPTable.getRows().forEach(x->{
            for (PdfPCell cell : x.getCells()) {
                if(ObjectUtils.isNotEmpty(cell)){
                    cell.setBorderWidthTop(0);
                    cell.setBorderWidthBottom(0);
                }
            }
        });
    }
}

/**
 * 设置页面附加属性
 *
 */
   class PdfPageEventHelperBuilder extends PdfPageEventHelper {

    /**
     * 页眉
     */
    //public String header = "itext测试页眉";

    /**
     * 文档字体大小,页脚页眉最好和文本大小一致
     */
    public int presentFontSize = 12;

    /**
     * 文档页面大小,最好前面传入,否则默认为A4纸张
     */
    public Rectangle pageSize = PageSize.A4;

    // 模板
    public PdfTemplate total;

    // 基础字体对象
    public BaseFont bf = null;

    // 利用基础字体生成的字体对象,一般用于生成中文文字
    public Font fontDetail = null;
    public PdfPageEventHelperBuilder() {
    }

    /**
     *
     * Creates a new instance of PdfReportM1HeaderFooter 构造方法.
     *
     * @param
     *
     * @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 PdfPageEventHelperBuilder( 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 文档打开时创建模板
     *
     */
    @Override
    public void onOpenDocument(PdfWriter writer, Document document) {
        total = writer.getDirectContent().createTemplate(50, 50);// 共 页 的矩形的长宽高
    }

    /**
     *
     * TODO 关闭每页的时候,写入页眉,写入'第几页共'这几个字。
     *
     */
    @Override
    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 | IOException e) {
            e.printStackTrace();
        }

        // 1.写入页眉
//        ColumnText.showTextAligned(writer.getDirectContent(),
//                Element.ALIGN_LEFT, new Phrase(header, fontDetail),
//                document.left(), document.top() + 20, 0);
        // 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() - 10, 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() - 10); // 调节模版显示的位置

    }

//    //加水印
//    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();
//        }
//    }

    /**
     *
     * TODO 关闭文档时,替换模板,完成整个页眉页脚组件
     *
     */
    @Override
    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) + " 页"; //页脚内容拼接  如  第1页/共2页
        //String foot2 = String.valueOf(writer.getPageNumber()); //页脚内容拼接  如  第1页/共2页
        total.showText(foot2);// 模版显示的内容
        total.endText();
        total.closePath();
    }
}



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值