Excel 转 PDF 并添加水印

本文介绍了如何使用Java和iTextPDF库将Excel文件转换为PDF,并实现PDF水印功能。涉及到的依赖如itextpdf、jxl和commons-io。展示了从读取Excel、转换到PDF,再到添加水印的具体步骤。
摘要由CSDN通过智能技术生成

pom文件包:

        <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itextpdf</artifactId>
            <version>5.5.5</version>
        </dependency>
        <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itext-asian</artifactId>
            <version>5.2.0</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.11.0</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/net.sourceforge.jexcelapi/jxl -->
        <dependency>
            <groupId>net.sourceforge.jexcelapi</groupId>
            <artifactId>jxl</artifactId>
            <version>2.6.12</version>
            <exclusions>
                <exclusion>
                    <artifactId>log4j</artifactId>
                    <groupId>log4j</groupId>
                </exclusion>
            </exclusions>
        </dependency>

JavaDome代码:

package dome;

import com.itextpdf.text.*;
import com.itextpdf.text.pdf.*;
import jxl.*;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import java.io.*;
import java.util.UUID;

/**
 * @projectName testDome
 * @date 2022/6/13 16:03
 */
public class excelToPdfDome {


    public static void main(String[] args) {
        String excelFilePath = "D:\\testDome\\11111111111.xls";
        excel2PdfAdWaterMark(excelFilePath,"仅供测试使用,不得对外传阅");
    }



    /**
     * @Description : Excel to PDF 并添加水印
     * @Date   : 2022/6/13 16:09
     * @param descExcelFilePath excel的路径地址
     * @param waterMarkName 水印文案
     **/
    public static void excel2PdfAdWaterMark(String descExcelFilePath, String waterMarkName){
        FileInputStream fileInputStream = null;
        InputStream inputStream = null;
        String descExcelToPdfFilePath = descExcelFilePath.replace(".xls", ".pdf");
        try {

            fileInputStream = new FileInputStream(descExcelFilePath);
            byte[] bytes = IOUtils.toByteArray(fileInputStream);
            inputStream = new ByteArrayInputStream(bytes);
            // jxl excel 转换为excel
            String tempFile = excelToPaf(descExcelFilePath);
            IOUtils.closeQuietly(inputStream);
            IOUtils.closeQuietly(fileInputStream);
            // 添加水印
            waterMark(tempFile, descExcelToPdfFilePath, waterMarkName);
            // 删除临时文件
            FileUtils.deleteQuietly(new File(tempFile));
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            IOUtils.closeQuietly(inputStream);
            IOUtils.closeQuietly(fileInputStream);
        }
    }

    /**
     * @param inputFile 你的PDF文件地址
     * @param outputFile 添加水印后生成PDF存放的地址
     * @param waterMarkName 你的水印
     * @return 是否添加成功
     */
    public static boolean waterMark(String inputFile,String outputFile, String waterMarkName) {
        try {
            PdfReader reader = new PdfReader(inputFile);
            PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(
                    outputFile));
            //这里的字体设置比较关键,这个设置是支持中文的写法// 使用系统字体
            BaseFont base = BaseFont.createFont("STSong-Light","UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
            int total = reader.getNumberOfPages() + 1;
            PdfContentByte under;
            Rectangle pageRect = null;
            for (int i = 1; i < total; i++) {
                pageRect = stamper.getReader().
                        getPageSizeWithRotation(i);
                // 计算水印X,Y坐标
                float x = pageRect.getWidth()/2;
                float y = pageRect.getHeight()/2+100;
                under = stamper.getUnderContent(i);
                under.saveState();
                PdfGState gs = new PdfGState();
                // 设置透明度为0.6
                gs.setFillOpacity(0.6f);
                under.setGState(gs);
                under.restoreState();
                under.beginText();
                // 水印字体大小
                under.setFontAndSize(base, 35);
                under.setTextMatrix(60, 60);
                // 颜色
                under.setColorFill(BaseColor.GRAY);
                // 水印文字成30度角倾斜,你可以随心所欲的改你自己想要的角度
                under.showTextAligned(Element.ALIGN_CENTER, waterMarkName,  x,  y, 45);
                // 添加水印文字
                under.endText();
                under.setLineWidth(1f);
                under.stroke();
            }
            stamper.close();
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }




    public static String excelToPaf(String filePath) throws Exception {
        String tempFilePath = File.createTempFile(UUID.randomUUID().toString(), ".pdf").getAbsolutePath();
        Document document = new Document(PageSize.A4,0,0,50,0);
        PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(tempFilePath));
        Workbook workbook = null;
        PdfPTable table = null;
        //字体设置
        /*
         * 由于itext不支持中文,所以需要进行字体的设置,我这里让itext调用windows系统的中文字体,
         * 找到文件后,打开属性,将文件名及所在路径作为字体名即可。
         */
        //创建BaseFont对象,指明字体,编码方式,是否嵌入
        //这里的字体设置比较关键,这个设置是支持中文的写法
        BaseFont baseFont = BaseFont.createFont("STSong-Light",
                "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED,false);// 使用系统字体
        try {
            workbook= Workbook.getWorkbook(new File(filePath));
            Sheet sheet = workbook.getSheet(0);
            int column=sheet.getColumns();
            table = new PdfPTable(column); // 实际创建的列数
            int[] widths = new int[column];
            for(int j=0;j<column;j++){
                CellView columnView = sheet.getColumnView(j);
                widths[j] = columnView.getSize();
            }
            table.setWidths(widths); // 适配excel宽度
            PdfPCell cell1;
            for(int i=0;i<sheet.getRows();i++){ // 行
                for(int j=0;j<sheet.getColumns();j++){ // 列
                    boolean flag = false;
                    Cell cell=   sheet.getCell(j, i);
                    String str = cell.getContents();
                    Font font= null;
                    if(str != null && !"".equals(str) ){
                        int boldWeight = cell.getCellFormat().getFont().getBoldWeight();
                        //创建Font对象,将基础字体对象,字体大小,字体风格
                        if(boldWeight == 700){ // 700:粗体
                            font = new Font(baseFont,13, Font.BOLD);
                        }else {// 400或其他 非粗体
                            font = new Font(baseFont,13, Font.NORMAL);
                        }
                    }else{
                        font = new Font(baseFont,13, Font.NORMAL);
                    }
                    flag = isMergeRegionsContainsCell(i, j, table, sheet, str, font);
                    if(!flag){
                        table.addCell(getPDFCell(str,font));
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            workbook.close();
            document.open();
            document.add(table); // 将表格加入到文档中,并写入pdf文件
            document.close();
            writer.close();
        }
        return tempFilePath;
    }

    //获取指定内容与字体的单元格
    private static PdfPCell getPDFCell(String string, Font font) {
        //创建单元格对象,将内容与字体放入段落中作为单元格内容
        PdfPCell cell = new PdfPCell(new Paragraph(string, font));
        cell.setHorizontalAlignment(Element.ALIGN_CENTER);
        cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        //设置最小单元格高度
        cell.setMinimumHeight(20);
        return cell;
    }


    /**
     * 单元格是否在合并区域内:true 在 false 不在
     * @param r
     * @param c
     * @param table
     * @param sheet
     * @param str
     * @param font
     * @return
     */
    private static boolean isMergeRegionsContainsCell(int r, int c, PdfPTable table, Sheet sheet, String str, Font font){
        Range[] ranges = sheet.getMergedCells();
        PdfPCell cell1 = null;
        for(Range range : ranges){    //合并的单元格判断和处理
            if(c >= range.getTopLeft().getColumn() && c <= range.getBottomRight().getColumn()
                    && r >= range.getTopLeft().getRow() && r <= range.getBottomRight().getRow()){
                if(str == null || "".equals(str)){
                    return true;
                }
                int rowNum = range.getBottomRight().getRow() - range.getTopLeft().getRow()+1;
                int colNum = range.getBottomRight().getColumn() - range.getTopLeft().getColumn()+1;
                if(rowNum > colNum){
                    cell1 = mergeRow(str, font, rowNum);
                    cell1.setColspan(colNum);
                    table.addCell(cell1);
                }else {
                    cell1 = mergeCol(str, font, colNum);
                    cell1.setRowspan(rowNum);
                    table.addCell(cell1);
                }
                return true;
            }
        }
        return false;
    }

    //合并行的静态函数
    private static PdfPCell mergeRow(String str, Font font, int i) {
        //创建单元格对象,将内容及字体传入
        PdfPCell cell = new PdfPCell(new Paragraph(str, font));
        //设置单元格内容居中
        cell.setHorizontalAlignment(Element.ALIGN_CENTER);
        cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        //将该单元格所在列包括该单元格在内的i行单元格合并为一个单元格
        cell.setRowspan(i);
        return cell;
    }

    //合并列的静态函数
    private static PdfPCell mergeCol(String str, Font font, int i) {
        PdfPCell cell = new PdfPCell(new Paragraph(str, font));
        cell.setMinimumHeight(25);
        cell.setHorizontalAlignment(Element.ALIGN_CENTER);
        cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        //将该单元格所在行包括该单元格在内的i列单元格合并为一个单元格
        cell.setColspan(i);
        return cell;
    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值