IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    Excel 转 PDF

    此间少年发表于 2024-11-27 01:10:00
    love 0

    自动识别 Excel 样式,转为 PDF 样式,可添加水印

    import com.itextpdf.text.Font;
    import com.itextpdf.text.*;
    import com.itextpdf.text.pdf.*;
    import com.itextpdf.text.pdf.interfaces.PdfViewerPreferences;
    import com.itextpdf.text.pdf.internal.PdfViewerPreferencesImp;
    import lombok.SneakyThrows;
    import org.apache.poi.ss.usermodel.*;
    import org.apache.poi.ss.util.CellRangeAddress;
    import org.apache.poi.xssf.usermodel.XSSFColor;
    import org.apache.poi.xssf.usermodel.XSSFFont;
    import org.apache.poi.xssf.usermodel.XSSFSheet;
    import org.apache.poi.xssf.usermodel.XSSFWorkbook;
    
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.OutputStream;
    import java.math.BigDecimal;
    import java.util.List;
    
    public class ExcelToPdf {
    
        /**
         * 转换 Excel 为 PDF 文件
         *
         * @param workbook       excel 文档
         * @param outputStream   pdf 输出流
         * @param watermarkText1 水印文本1
         * @param watermarkText2 水印文本2
         */
        public static void convertExcelToPDF(XSSFWorkbook workbook, OutputStream outputStream, String watermarkText1, String watermarkText2) throws IOException, DocumentException {
            if (workbook.getNumberOfSheets() <= 0) {
                Document document = new Document();
                PdfWriter instance = PdfWriter.getInstance(document, outputStream);
                instance.setPageEvent(new WatermarkPageEvent(watermarkText1, watermarkText2));
                document.open();
                document.add(new Paragraph(" "));
                document.close();
                workbook.close();
                return;
            }
            // 获取 Excel 列宽度(假设第一列的宽度为 PDF 页面宽度)
            float excelColumnWidth = workbook.getSheetAt(0).getColumnWidth(0);
            Document document = new Document(new Rectangle(excelColumnWidth, 842));
            PdfWriter instance = PdfWriter.getInstance(document, outputStream);
            instance.setPageEvent(new WatermarkPageEvent(watermarkText1, watermarkText2));
            document.open();
            for (int i = 0; i < workbook.getNumberOfSheets(); i++) {
                XSSFSheet worksheet = workbook.getSheetAt(i);
                // sheet 去除密码保护
                worksheet.protectSheet("****");
                worksheet.protectSheet(null);
                createAndAddTable(worksheet, document);
                if (i < workbook.getNumberOfSheets() - 1) {
                    document.newPage();
                }
            }
            document.close();
            workbook.close();
        }
    
        /**
         * 新增表格
         *
         * @param worksheet Excel 工作簿
         * @param document  PDF 文档
         */
        private static void createAndAddTable(XSSFSheet worksheet, Document document) throws DocumentException, IOException {
            if (worksheet.getRow(0) == null) {
                document.newPage();
                document.add(new Paragraph(" "));
                return;
            }
            // 创建表格,根据 Excel 的第一行,获取需要创建的列数
            PdfPTable table = new PdfPTable(worksheet.getRow(0).getPhysicalNumberOfCells());
            // 设置表格宽度
            table.setWidthPercentage(100);
            table.setLockedWidth(false);
            // 添加表格数据
            addTableData(worksheet, table);
            // 合并单元格
            mergeTableCell(worksheet, table);
            // 将表格加入 PDF 文档
            document.add(table);
        }
    
        // 合并单元格
        private static void mergeTableCell(XSSFSheet worksheet, PdfPTable table) {
            List<CellRangeAddress> mergedRegions = worksheet.getMergedRegions();
            for (CellRangeAddress mergedRegion : mergedRegions) {
                PdfPRow row = table.getRow(mergedRegion.getFirstRow());
                int mergeCell = mergedRegion.getLastColumn() - mergedRegion.getFirstColumn();
                // +1 是因为起始单元格占 1 个格子
                row.getCells()[mergedRegion.getFirstColumn()].setColspan(mergeCell + 1);
            }
        }
    
        // 获取 Excel 单元格内容
        public static String getCellText(Cell cell) {
            if (cell == null) {
                return "";
            }
            String cellValue;
            switch (cell.getCellTypeEnum()) {
                case STRING:
                    cellValue = cell.getStringCellValue();
                    break;
                case NUMERIC:
                    cellValue = String.valueOf(BigDecimal.valueOf(cell.getNumericCellValue()));
                    break;
                case BLANK:
                default:
                    cellValue = "";
                    break;
            }
            return cellValue;
        }
    
        // 添加表格数据
        private static void addTableData(XSSFSheet worksheet, PdfPTable table) throws DocumentException, IOException {
            for (Row row : worksheet) {
                for (int i = 0; i < row.getPhysicalNumberOfCells(); i++) {
                    Cell cell = row.getCell(i);
                    if (cell == null) {
                        continue;
                    }
                    String cellValue = getCellText(cell);
                    // 创建单元格,填充文本和字体相关样式
                    PdfPCell cellPdf = new PdfPCell(new Phrase(cellValue, getCellStyle(cell)));
                    // 设置单元格背景色
                    setBackgroundColor(cell, cellPdf);
                    // 设置单元格中内容对齐方式
                    setCellAlignment(cell, cellPdf);
                    // 将单元格加入 PDF 中
                    table.addCell(cellPdf);
                }
            }
        }
    
        // 设置背景
        private static void setBackgroundColor(Cell cell, PdfPCell cellPdf) {
            short bgColorIndex = cell.getCellStyle().getFillForegroundColor();
            // 是否自动背景色
            if (bgColorIndex != IndexedColors.AUTOMATIC.getIndex()) {
                XSSFColor bgColor = (XSSFColor) cell.getCellStyle().getFillForegroundColorColor();
                if (bgColor != null) {
                    String argbHex = bgColor.getARGBHex();
                    int argb = (int) Long.parseLong(argbHex.substring(1), 16); // 将 hex 颜色转为 rgb
                    int red = (argb >> 16) & 0xFF; // 提取红色部分
                    int green = (argb >> 8) & 0xFF; // 提取绿色部分
                    int blue = argb & 0xFF; // 提取蓝色部分
                    cellPdf.setBackgroundColor(new BaseColor(red, green, blue));
                }
            }
        }
    
        // 设置单元格对齐方式
        private static void setCellAlignment(Cell cell, PdfPCell cellPdf) {
            CellStyle cellStyle = cell.getCellStyle();
            HorizontalAlignment horizontalAlignment = cellStyle.getAlignmentEnum();
            VerticalAlignment verticalAlignment = cellStyle.getVerticalAlignmentEnum();
            switch (horizontalAlignment) {
                case LEFT:
                    cellPdf.setHorizontalAlignment(Element.ALIGN_LEFT);
                    break;
                case CENTER:
                    cellPdf.setHorizontalAlignment(Element.ALIGN_CENTER);
                    break;
                case JUSTIFY:
                case FILL:
                    cellPdf.setVerticalAlignment(Element.ALIGN_JUSTIFIED);
                    break;
                case RIGHT:
                    cellPdf.setHorizontalAlignment(Element.ALIGN_RIGHT);
                    break;
            }
            switch (verticalAlignment) {
                case TOP:
                    cellPdf.setVerticalAlignment(Element.ALIGN_TOP);
                    break;
                case CENTER:
                    cellPdf.setVerticalAlignment(Element.ALIGN_MIDDLE);
                    break;
                case JUSTIFY:
                    cellPdf.setVerticalAlignment(Element.ALIGN_JUSTIFIED);
                    break;
                case BOTTOM:
                    cellPdf.setVerticalAlignment(Element.ALIGN_BOTTOM);
                    break;
            }
        }
    
        // 获取单元格内容样式
        private static Font getCellStyle(Cell cell) throws DocumentException, IOException {
            Font font = new Font(BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", true));
            CellStyle cellStyle = cell.getCellStyle();
            org.apache.poi.ss.usermodel.Font cellFont = cell.getSheet()
                .getWorkbook()
                .getFontAt(cellStyle.getFontIndex());
            // 字体颜色
            short fontColorIndex = cellFont.getColor();
            if (fontColorIndex != IndexedColors.AUTOMATIC.getIndex() && cellFont instanceof XSSFFont) {
                XSSFColor fontColor = ((XSSFFont) cellFont).getXSSFColor();
                if (fontColor != null) {
                    byte[] rgb = fontColor.getRGB();
                    if (rgb != null && rgb.length == 3) {
                        font.setColor(new BaseColor(rgb[0] & 0xFF, rgb[1] & 0xFF, rgb[2] & 0xFF));
                    }
                }
            }
            if (cellFont.getItalic()) {
                font.setStyle(Font.ITALIC);
            }
            if (cellFont.getStrikeout()) {
                font.setStyle(Font.STRIKETHRU);
            }
            if (cellFont.getUnderline() == 1) {
                font.setStyle(Font.UNDERLINE);
            }
            // 设置字体大小
            short fontSize = cellFont.getFontHeightInPoints();
            font.setSize(fontSize);
            if (cellFont.getBold()) {
                font.setStyle(Font.BOLD);
            }
            // 设置字体
            String fontName = cellFont.getFontName();
            if (FontFactory.isRegistered(fontName)) {
                font.setFamily(fontName);
            } else {
                font.setFamily("Helvetica");
            }
            return font;
        }
    }

    WatermarkPageEvent 水印

    import cn.hutool.core.util.StrUtil;
    import com.itextpdf.text.*;
    import com.itextpdf.text.pdf.*;
    import lombok.SneakyThrows;
    
    public class WatermarkPageEvent extends PdfPageEventHelper {
    
        /**
         * 水印1
         */
        Phrase watermark1;
    
        /**
         * 水印2
         */
        Phrase watermark2;
    
        Font font;
    
        @SneakyThrows
        public WatermarkPageEvent(String watermarkText1, String watermarkText2) {
            font = new Font(BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", true), 15);
            font.setColor(new BaseColor(192, 192, 192, 255));
            if (StrUtil.isNotBlank(watermarkText1)) {
                watermark1 = new Phrase(watermarkText1, font);
            }
            if (StrUtil.isNotBlank(watermarkText2)) {
                watermark2 = new Phrase(watermarkText2, font);
            }
        }
    
        @Override
        public void onEndPage(PdfWriter writer, Document document) {
            float height = document.getPageSize().getHeight();
            float width = document.getPageSize().getWidth();
            PdfContentByte directContentUnder = writer.getDirectContentUnder();
            if (watermark1 != null) {
                for (int y = 200; y <= height; y += 400) {
                    for (int x = 100; x <= width; x += 200) {
                        ColumnText.showTextAligned(directContentUnder, Element.ALIGN_CENTER, watermark1, x, y, 45);
                        ColumnText.showTextAligned(directContentUnder, Element.ALIGN_CENTER, watermark1, x, y, 45);
                        ColumnText.showTextAligned(directContentUnder, Element.ALIGN_CENTER, watermark1, x, y, 45);
                    }
                }
            }
            if (watermark2 != null) {
                for (int y = 180; y <= height; y += 400) {
                    for (int x = 110; x <= width; x += 200) {
                        ColumnText.showTextAligned(directContentUnder, Element.ALIGN_CENTER, watermark2, x, y, 45);
                        ColumnText.showTextAligned(directContentUnder, Element.ALIGN_CENTER, watermark2, x, y, 45);
                        ColumnText.showTextAligned(directContentUnder, Element.ALIGN_CENTER, watermark2, x, y, 45);
                    }
                }
            }
        }
    
    }


沪ICP备19023445号-2号
友情链接