Java Excel转PDF(免费)

天航星
• 阅读 534

目前市面上 Excel 转 PDF 的组件较多:

  • 收费:aspose、GcExcel、spire
  • 开源:jacob、itextpdf

其中收费的组件封装得比较好,代码简洁,转换的效果也很好,但收费也高得离谱: Java Excel转PDF(免费) 为了成本考虑,就需要考虑开源的组件了,因为它们都是免费的:

  • jacob:目前没有探索出很好的导出效果。
  • itextpdf:已探索出很好的导出效果,达到了与收费组件一致的效果(推荐)。

以下是 itextpdf 的使用步骤:

  1. 引入依赖

     <!-- POI Excel-->
     <dependency>
         <groupId>org.apache.poi</groupId>
         <artifactId>poi</artifactId>
         <version>4.1.1</version>
     </dependency>
    
     <!-- iText PDF -->
     <dependency>
         <groupId>com.itextpdf</groupId>
         <artifactId>itextpdf</artifactId>
         <version>5.5.13.2</version>
     </dependency>
  2. 定义图片信息

     import java.io.Serializable;
    
     /**
      * 图片信息
      */
     public class PicturesInfo implements Serializable {
    
         private static final long serialVersionUID = 1L;
    
         /**
          * 最小行
          */
         private int minRow;
    
         /**
          * 最大行
          */
         private int maxRow;
    
         /**
          * 最小列
          */
         private int minCol;
    
         /**
          * 最大列
          */
         private int maxCol;
    
         /**
          * 扩展
          */
         private String ext;
    
         /**
          * 图片数据
          */
         private byte[] pictureData;
    
         public int getMinRow() {
             return minRow;
         }
    
         public PicturesInfo setMinRow(int minRow) {
             this.minRow = minRow;
             return this;
         }
    
         public int getMaxRow() {
             return maxRow;
         }
    
         public PicturesInfo setMaxRow(int maxRow) {
             this.maxRow = maxRow;
             return this;
         }
    
         public int getMinCol() {
             return minCol;
         }
    
         public PicturesInfo setMinCol(int minCol) {
             this.minCol = minCol;
             return this;
         }
    
         public int getMaxCol() {
             return maxCol;
         }
    
         public PicturesInfo setMaxCol(int maxCol) {
             this.maxCol = maxCol;
             return this;
         }
    
         public String getExt() {
             return ext;
         }
    
         public PicturesInfo setExt(String ext) {
             this.ext = ext;
             return this;
         }
    
         public byte[] getPictureData() {
             return pictureData;
         }
    
         public PicturesInfo setPictureData(byte[] pictureData) {
             this.pictureData = pictureData;
             return this;
         }
     }
  3. 定义工具类

     import cn.hutool.core.collection.CollUtil;
     import cn.hutool.core.util.StrUtil;
     import com.itextpdf.text.BaseColor;
     import com.itextpdf.text.Document;
     import com.itextpdf.text.DocumentException;
     import com.itextpdf.text.Image;
     import com.itextpdf.text.PageSize;
     import com.itextpdf.text.Phrase;
     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 lombok.experimental.UtilityClass;
     import org.apache.log4j.Logger;
     import org.apache.poi.hssf.usermodel.HSSFCell;
     import org.apache.poi.hssf.usermodel.HSSFClientAnchor;
     import org.apache.poi.hssf.usermodel.HSSFPicture;
     import org.apache.poi.hssf.usermodel.HSSFPictureData;
     import org.apache.poi.hssf.usermodel.HSSFShape;
     import org.apache.poi.hssf.usermodel.HSSFShapeContainer;
     import org.apache.poi.hssf.usermodel.HSSFSheet;
     import org.apache.poi.hssf.usermodel.HSSFWorkbook;
     import org.apache.poi.ooxml.POIXMLDocumentPart;
     import org.apache.poi.ss.usermodel.Cell;
     import org.apache.poi.ss.usermodel.CellType;
     import org.apache.poi.ss.usermodel.DataFormatter;
     import org.apache.poi.ss.usermodel.DateUtil;
     import org.apache.poi.ss.usermodel.Font;
     import org.apache.poi.ss.usermodel.Row;
     import org.apache.poi.ss.usermodel.Sheet;
     import org.apache.poi.ss.usermodel.Workbook;
     import org.apache.poi.ss.util.CellRangeAddress;
     import org.apache.poi.xssf.usermodel.XSSFCell;
     import org.apache.poi.xssf.usermodel.XSSFClientAnchor;
     import org.apache.poi.xssf.usermodel.XSSFDrawing;
     import org.apache.poi.xssf.usermodel.XSSFPicture;
     import org.apache.poi.xssf.usermodel.XSSFPictureData;
     import org.apache.poi.xssf.usermodel.XSSFShape;
     import org.apache.poi.xssf.usermodel.XSSFSheet;
     import org.apache.poi.xssf.usermodel.XSSFWorkbook;
     import java.io.IOException;
     import java.io.InputStream;
     import java.io.OutputStream;
     import java.nio.file.Files;
     import java.nio.file.Paths;
     import java.text.SimpleDateFormat;
     import java.util.ArrayList;
     import java.util.Date;
     import java.util.HashSet;
     import java.util.List;
     import java.util.Objects;
     import java.util.Set;
    
     /**
      * Excel转PDF
      * @author 廖航
      * @date 2024-08-29 10:52
      */
     @UtilityClass
     public class ExcelToPdfUtil {
    
         /**
          * 日志输出
          */
         private static final Logger logger = Logger.getLogger(ExcelToPdfUtil.class);
    
         /**
          * 单元格队列
          */
         Set<String> cellSet = new HashSet<>();
    
         /**
          * Excel转PDF
          * 
          * @param excelPath Excel文件路径
          * @param pdfPath PDF文件路径
          * @param excelSuffix Excel文件后缀
          */
         public static void excelToPdf(String excelPath, String pdfPath, String excelSuffix) {
             try (InputStream in = Files.newInputStream(Paths.get(excelPath));
                  OutputStream out = Files.newOutputStream(Paths.get(pdfPath))) {
                 ExcelToPdfUtil.excelToPdf(in, out, excelSuffix);
             } catch (Exception e) {
                 logger.error(e.getMessage());
             }
         }
    
         /**
          * Excel转PDF并写入输出流
          *
          * @param inStream    Excel输入流
          * @param outStream   PDF输出流
          * @param excelSuffix Excel类型 .xls 和 .xlsx
          * @throws Exception 异常信息
          */
         public static void excelToPdf(InputStream inStream, OutputStream outStream, String excelSuffix) throws Exception {
             // 输入流转workbook,获取sheet
             Sheet sheet = getPoiSheetByFileStream(inStream, 0, excelSuffix);
             // 获取列宽度占比
             float[] widths = getColWidth(sheet);
             PdfPTable table = new PdfPTable(widths);
             table.setWidthPercentage(100);
             int colCount = widths.length;
             //设置基本字体
             BaseFont baseFont = BaseFont.createFont("C:\\Windows\\Fonts\\simsun.ttc,0", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
             // 遍历行
             for (int rowIndex = sheet.getFirstRowNum(); rowIndex <= sheet.getLastRowNum(); rowIndex++) {
                 Row row = sheet.getRow(rowIndex);
                 if (Objects.isNull(row)) {
                     // 插入空对象
                     for (int i = 0; i < colCount; i++) {
                         table.addCell(createPdfPCell(null, 0, 13f, null));
                     }
                 } else {
                     // 遍历单元格
                     for (int columnIndex = 0; (columnIndex < row.getLastCellNum() || columnIndex < colCount) && columnIndex > -1; columnIndex++) {
                         PdfPCell pCell = excelCellToPdfCell(sheet, row.getCell(columnIndex), baseFont);
                         // 是否合并单元格
                         if (isMergedRegion(sheet, rowIndex, columnIndex)) {
                             int[] span = getMergedSpan(sheet, rowIndex, columnIndex);
                             //忽略合并过的单元格
                             boolean mergedCell = span[0] == 1 && span[1] == 1;
                             if (mergedCell) {
                                 continue;
                             }
                             pCell.setRowspan(span[0]);
                             pCell.setColspan(span[1]);
                         }
                         table.addCell(pCell);
                     }
                 }
             }
             // 初始化PDF文档对象
             createPdfTableAndWriteDocument(outStream, table);
         }
    
         /**
          * 单元格转换,poi cell 转换为 itext cell
          *
          * @param sheet     poi sheet页
          * @param excelCell poi 单元格
          * @param baseFont  基础字体
          * @return PDF单元格
          */
         private static PdfPCell excelCellToPdfCell(Sheet sheet, Cell excelCell, BaseFont baseFont) throws Exception {
             if (Objects.isNull(excelCell)) {
                 return createPdfPCell(null, 0, 13f, null);
             }
             int rowIndex = excelCell.getRowIndex();
             int columnIndex = excelCell.getColumnIndex();
             // 图片信息
             List<PicturesInfo> infos = getAllPictureInfos(sheet, rowIndex, rowIndex, columnIndex, columnIndex, false);
             PdfPCell pCell;
             if (CollUtil.isNotEmpty(infos)) {
                 Image image = Image.getInstance(infos.get(0).getPictureData());
                 // 调整图片大小
                 image.scaleAbsolute(527, 215);
                 pCell = new PdfPCell(image);
             } else {
                 Font excelFont = getExcelFont(sheet, excelCell);
                 //设置单元格字体
                 com.itextpdf.text.Font pdFont = new com.itextpdf.text.Font(baseFont, excelFont.getFontHeightInPoints(), excelFont.getBold() ? 1 : 0, BaseColor.BLACK);
                 Integer border = hasBorder(excelCell) ? null : 0;
                 String excelCellValue = getExcelCellValue(excelCell);
                 pCell = createPdfPCell(excelCellValue, border, excelCell.getRow().getHeightInPoints(), pdFont);
             }
             // 水平居中
             pCell.setHorizontalAlignment(getHorAlign(excelCell.getCellStyle().getAlignment().getCode()));
             // 垂直对齐
             pCell.setVerticalAlignment(getVerAlign(excelCell.getCellStyle().getVerticalAlignment().getCode()));
             return pCell;
         }
    
         /**
          * 创建pdf文档,并添加表格
          *
          * @param outStream 输出流,目标文档
          * @param table     表格
          * @throws DocumentException 异常信息
          */
         private static void createPdfTableAndWriteDocument(OutputStream outStream, PdfPTable table) throws DocumentException {
             //设置pdf纸张大小 PageSize.A4 A4横向
             Document document = new Document(PageSize.B0);
             PdfWriter.getInstance(document, outStream);
             //设置页边距 宽
             document.setMargins(10, 10, 10, 10);
             document.open();
             document.add(table);
             document.close();
         }
    
         /**
          * Excel文档输入流转换为对应的workbook及获取对应的sheet
          *
          * @param inputStream Excel文档输入流
          * @param sheetNo     sheet编号,默认0 第一个sheet
          * @param excelSuffix 文件类型 .xls和.xlsx
          * @return poi sheet
          * @throws IOException 异常
          */
         public static Sheet getPoiSheetByFileStream(InputStream inputStream, int sheetNo, String excelSuffix) throws IOException {
             Workbook workbook;
             if (excelSuffix.endsWith(".xlsx")) {
                 workbook = new XSSFWorkbook(inputStream);
             } else {
                 workbook = new HSSFWorkbook(inputStream);
             }
             return workbook.getSheetAt(sheetNo);
         }
    
         /**
          * 创建itext pdf 单元格
          *
          * @param content       单元格内容
          * @param border        边框
          * @param minimumHeight 高度
          * @param pdFont        字体
          * @return pdf cell
          */
         private static PdfPCell createPdfPCell(String content, Integer border, Float minimumHeight, com.itextpdf.text.Font pdFont) {
             String contentValue = content == null ? "" : content;
             com.itextpdf.text.Font pdFontNew = pdFont == null ? new com.itextpdf.text.Font() : pdFont;
             PdfPCell pCell = new PdfPCell(new Phrase(contentValue, pdFontNew));
             if (Objects.nonNull(border)) {
                 pCell.setBorder(border);
             }
             if (Objects.nonNull(minimumHeight)) {
                 pCell.setMinimumHeight(minimumHeight);
             }
    
             return pCell;
         }
    
         /**
          * excel垂直对齐方式映射到pdf对齐方式
          * 
          * @param align 对齐
          * @return 结果
          */
         private static int getVerAlign(int align) {
             switch (align) {
                 case 2:
                     return com.itextpdf.text.Element.ALIGN_BOTTOM;
                 case 3:
                     return com.itextpdf.text.Element.ALIGN_TOP;
                 default:
                     return com.itextpdf.text.Element.ALIGN_MIDDLE;
             }
         }
    
         /**
          * excel水平对齐方式映射到pdf水平对齐方式
          * 
          * @param align 对齐
          * @return 结果
          */
         private static int getHorAlign(int align) {
             switch (align) {
                 case 1:
                     return com.itextpdf.text.Element.ALIGN_LEFT;
                 case 3:
                     return com.itextpdf.text.Element.ALIGN_RIGHT;
                 default:
                     return com.itextpdf.text.Element.ALIGN_CENTER;
             }
         }
    
         /*============================================== POI获取图片及文本内容工具方法 ==============================================*/
    
         /**
          * 获取字体
          *
          * @param sheet excel 转换的sheet页
          * @param cell  单元格
          * @return 字体
          */
         private static Font getExcelFont(Sheet sheet, Cell cell) {
             // xls
             if (sheet instanceof HSSFSheet) {
                 Workbook workbook = sheet.getWorkbook();
                 return ((HSSFCell) cell).getCellStyle().getFont(workbook);
             }
             // xlsx
             return ((XSSFCell) cell).getCellStyle().getFont();
         }
    
         /**
          * 判断excel单元格是否有边框
          * 
          * @param excelCell 单元格
          * @return 结果
          */
         private static boolean hasBorder(Cell excelCell) {
             short top = excelCell.getCellStyle().getBorderTop().getCode();
             short bottom = excelCell.getCellStyle().getBorderBottom().getCode();
             short left = excelCell.getCellStyle().getBorderLeft().getCode();
             short right = excelCell.getCellStyle().getBorderRight().getCode();
             return top + bottom + left + right > 2;
         }
    
         /**
          * 判断单元格是否是合并单元格
          * 
          * @param sheet 表
          * @param row 行
          * @param column 列
          * @return 结果
          */
         private static boolean isMergedRegion(Sheet sheet, int row, int column) {
             int sheetMergeCount = sheet.getNumMergedRegions();
             for (int i = 0; i < sheetMergeCount; i++) {
                 CellRangeAddress range = sheet.getMergedRegion(i);
                 int firstColumn = range.getFirstColumn();
                 int lastColumn = range.getLastColumn();
                 int firstRow = range.getFirstRow();
                 int lastRow = range.getLastRow();
                 if (row >= firstRow && row <= lastRow) {
                     if (column >= firstColumn && column <= lastColumn) {
                         return true;
                     }
                 }
             }
             return false;
         }
    
         /**
          * 计算合并单元格合并的跨行跨列数
          * 
          * @param sheet 表
          * @param row 行
          * @param column 列
          * @return 结果
          */
         private static int[] getMergedSpan(Sheet sheet, int row, int column) {
             int sheetMergeCount = sheet.getNumMergedRegions();
             int[] span = {1, 1};
             for (int i = 0; i < sheetMergeCount; i++) {
                 CellRangeAddress range = sheet.getMergedRegion(i);
                 int firstColumn = range.getFirstColumn();
                 int lastColumn = range.getLastColumn();
                 int firstRow = range.getFirstRow();
                 int lastRow = range.getLastRow();
                 if (firstColumn == column && firstRow == row) {
                     span[0] = lastRow - firstRow + 1;
                     span[1] = lastColumn - firstColumn + 1;
                     break;
                 }
             }
             return span;
         }
    
         /**
          * 获取excel中每列宽度的占比
          * 
          * @param sheet 表
          * @return 结果
          */
         private static float[] getColWidth(Sheet sheet) {
             int rowNum = getMaxColRowNum(sheet);
             Row row = sheet.getRow(rowNum);
             int cellCount = row.getPhysicalNumberOfCells();
             int[] colWidths = new int[cellCount];
             int sum = 0;
    
             for (int i = row.getFirstCellNum(); i < cellCount; i++) {
                 Cell cell = row.getCell(i);
                 if (cell != null) {
                     colWidths[i] = sheet.getColumnWidth(i);
                     sum += sheet.getColumnWidth(i);
                 }
             }
    
             float[] colWidthPer = new float[cellCount];
             for (int i = row.getFirstCellNum(); i < cellCount; i++) {
                 colWidthPer[i] = (float) colWidths[i] / sum * 100;
             }
             return colWidthPer;
         }
    
         /**
          * 获取excel中列数最多的行号
          * 
          * @param sheet 表
          * @return 结果
          */
         private static int getMaxColRowNum(Sheet sheet) {
             int rowNum = 0;
             int maxCol = 0;
             for (int r = sheet.getFirstRowNum(); r < sheet.getPhysicalNumberOfRows(); r++) {
                 Row row = sheet.getRow(r);
                 if (row != null && maxCol < row.getPhysicalNumberOfCells()) {
                     maxCol = row.getPhysicalNumberOfCells();
                     rowNum = r;
                 }
             }
             return rowNum;
         }
    
         /**
          * poi 根据单元格类型获取单元格内容
          *
          * @param excelCell poi单元格
          * @return 单元格内容文本
          */
         public static String getExcelCellValue(Cell excelCell) {
             if (excelCell == null) {
                 return "";
             }
             // 判断数据的类型
             CellType cellType = excelCell.getCellType();
    
             if (cellType == CellType.STRING) {
                 return excelCell.getStringCellValue();
             }
             if (cellType == CellType.BOOLEAN) {
                 return String.valueOf(excelCell.getBooleanCellValue());
             }
             if (cellType == CellType.FORMULA) {
                 return excelCell.getCellFormula();
             }
             if (cellType == CellType.NUMERIC) {
                 // 处理日期格式、时间格式
                 if (DateUtil.isCellDateFormatted(excelCell)) {
                     SimpleDateFormat sdf;
                     // 验证short值
                     if (excelCell.getCellStyle().getDataFormat() == 14) {
                         sdf = new SimpleDateFormat("yyyy/MM/dd");
                     } else if (excelCell.getCellStyle().getDataFormat() == 21) {
                         sdf = new SimpleDateFormat("HH:mm:ss");
                     } else if (excelCell.getCellStyle().getDataFormat() == 22) {
                         sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
                     } else {
                         throw new RuntimeException("日期格式错误!!!");
                     }
                     Date date = excelCell.getDateCellValue();
                     return sdf.format(date);
                 } else if (excelCell.getCellStyle().getDataFormat() == 0) {
                     //处理数值格式
                     DataFormatter formatter = new DataFormatter();
                     return formatter.formatCellValue(excelCell);
                 }
             }
             if (cellType == CellType.ERROR) {
                 return "非法字符";
             }
             return "";
         }
    
         /**
          * 获取sheet内的所有图片信息
          *
          * @param sheet        sheet表
          * @param onlyInternal 单元格内部
          * @return 照片集合
          * @throws Exception 异常
          */
         public static List<PicturesInfo> getAllPictureInfos(Sheet sheet, boolean onlyInternal) throws Exception {
             return getAllPictureInfos(sheet, null, null, null, null, onlyInternal);
         }
    
         /**
          * 根据sheet和单元格信息获取图片
          *
          * @param sheet        sheet表
          * @param minRow       最小行
          * @param maxRow       最大行
          * @param minCol       最小列
          * @param maxCol       最大列
          * @param onlyInternal 是否内部
          * @return 图片集合
          * @throws Exception 异常
          */
         public static List<PicturesInfo> getAllPictureInfos(Sheet sheet, Integer minRow, Integer maxRow, Integer minCol,
                                                             Integer maxCol, boolean onlyInternal) throws Exception {
             if (sheet instanceof HSSFSheet) {
                 return getXLSAllPictureInfos((HSSFSheet) sheet, minRow, maxRow, minCol, maxCol, onlyInternal);
             } else if (sheet instanceof XSSFSheet) {
                 return getXLSXAllPictureInfos((XSSFSheet) sheet, minRow, maxRow, minCol, maxCol, onlyInternal);
             } else {
                 throw new Exception("未处理类型,没有为该类型添加:GetAllPicturesInfos()扩展方法!");
             }
         }
    
         /**
          * 获取XLS图片信息
          * 
          * @param sheet 表
          * @param minRow 最小行
          * @param maxRow 最大行
          * @param minCol 最小列
          * @param maxCol 最大列
          * @param onlyInternal 只在内部
          * @return 图片信息列表
          */
         private static List<PicturesInfo> getXLSAllPictureInfos(HSSFSheet sheet, Integer minRow, Integer maxRow,
                                                                 Integer minCol, Integer maxCol, Boolean onlyInternal) {
             List<PicturesInfo> picturesInfoList = new ArrayList<>();
             HSSFShapeContainer shapeContainer = sheet.getDrawingPatriarch();
             if (shapeContainer == null) {
                 return picturesInfoList;
             }
             List<HSSFShape> shapeList = shapeContainer.getChildren();
             for (HSSFShape shape : shapeList) {
                 if (shape instanceof HSSFPicture && shape.getAnchor() instanceof HSSFClientAnchor) {
                     HSSFPicture picture = (HSSFPicture) shape;
                     HSSFClientAnchor anchor = (HSSFClientAnchor) shape.getAnchor();
    
                     if (isInternalOrIntersect(minRow, maxRow, minCol, maxCol, anchor.getRow1(), anchor.getRow2(),
                             anchor.getCol1(), anchor.getCol2(), onlyInternal)) {
                         String item = StrUtil.format("{},{},{},{}", anchor.getRow1(), anchor.getRow2(), anchor.getCol1(), anchor.getCol2());
                         if (cellSet.contains(item)) {
                             continue;
                         }
                         cellSet.add(item);
                         HSSFPictureData pictureData = picture.getPictureData();
                         picturesInfoList.add(new PicturesInfo()
                                 .setMinRow(anchor.getRow1())
                                 .setMaxRow(anchor.getRow2())
                                 .setMinCol(anchor.getCol1())
                                 .setMaxCol(anchor.getCol2())
                                 .setPictureData(pictureData.getData())
                                 .setExt(pictureData.getMimeType()));
                     }
                 }
             }
             return picturesInfoList;
         }
    
         /**
          * 获取XLSX图片信息
          * 
          * @param sheet 表
          * @param minRow 最小行
          * @param maxRow 最大行
          * @param minCol 最小列
          * @param maxCol 最大列
          * @param onlyInternal 只在内部
          * @return 图片信息列表
          */
         private static List<PicturesInfo> getXLSXAllPictureInfos(XSSFSheet sheet, Integer minRow, Integer maxRow,
                                                                  Integer minCol, Integer maxCol, Boolean onlyInternal) {
             List<PicturesInfo> picturesInfoList = new ArrayList<>();
    
             List<POIXMLDocumentPart> documentPartList = sheet.getRelations();
             for (POIXMLDocumentPart documentPart : documentPartList) {
                 if (documentPart instanceof XSSFDrawing) {
                     XSSFDrawing drawing = (XSSFDrawing) documentPart;
                     List<XSSFShape> shapes = drawing.getShapes();
                     for (XSSFShape shape : shapes) {
                         if (shape instanceof XSSFPicture) {
                             XSSFPicture picture = (XSSFPicture) shape;
                             XSSFClientAnchor anchor = picture.getPreferredSize();
    
                             if (isInternalOrIntersect(minRow, maxRow, minCol, maxCol, anchor.getRow1(), anchor.getRow2(),
                                     anchor.getCol1(), anchor.getCol2(), onlyInternal)) {
                                 String item = StrUtil.format("{},{},{},{}", anchor.getRow1(), anchor.getRow2(), anchor.getCol1(), anchor.getCol2());
                                 if (cellSet.contains(item)) {
                                     continue;
                                 }
                                 cellSet.add(item);
                                 XSSFPictureData pictureData = picture.getPictureData();
                                 picturesInfoList.add(new PicturesInfo()
                                         .setMinRow(anchor.getRow1())
                                         .setMaxRow(anchor.getRow2())
                                         .setMinCol(anchor.getCol1())
                                         .setMaxCol(anchor.getCol2())
                                         .setPictureData(pictureData.getData())
                                         .setExt(pictureData.getMimeType()));
                             }
                         }
                     }
                 }
             }
    
             return picturesInfoList;
         }
    
         /**
          * 是内部的或相交的
          * 
          * @param rangeMinRow 最小行范围
          * @param rangeMaxRow 最大行范围
          * @param rangeMinCol 最小列范围
          * @param rangeMaxCol 最大列范围
          * @param pictureMinRow 图片最小行
          * @param pictureMaxRow 图片最大行
          * @param pictureMinCol 图片最小列
          * @param pictureMaxCol 图片最大列
          * @param onlyInternal 只在内部
          * @return 结果
          */
         private static boolean isInternalOrIntersect(Integer rangeMinRow, Integer rangeMaxRow, Integer rangeMinCol,
                                                      Integer rangeMaxCol, int pictureMinRow, int pictureMaxRow, int pictureMinCol, int pictureMaxCol,
                                                      Boolean onlyInternal) {
             int _rangeMinRow = rangeMinRow == null ? pictureMinRow : rangeMinRow;
             int _rangeMaxRow = rangeMaxRow == null ? pictureMaxRow : rangeMaxRow;
             int _rangeMinCol = rangeMinCol == null ? pictureMinCol : rangeMinCol;
             int _rangeMaxCol = rangeMaxCol == null ? pictureMaxCol : rangeMaxCol;
    
             if (onlyInternal) {
                 return (_rangeMinRow <= pictureMinRow && _rangeMaxRow >= pictureMaxRow && _rangeMinCol <= pictureMinCol
                         && _rangeMaxCol >= pictureMaxCol);
             } else {
                 return ((Math.abs(_rangeMaxRow - _rangeMinRow) + Math.abs(pictureMaxRow - pictureMinRow) >= Math
                         .abs(_rangeMaxRow + _rangeMinRow - pictureMaxRow - pictureMinRow))
                         && (Math.abs(_rangeMaxCol - _rangeMinCol) + Math.abs(pictureMaxCol - pictureMinCol) >= Math
                         .abs(_rangeMaxCol + _rangeMinCol - pictureMaxCol - pictureMinCol)));
             }
         }
     }
  4. 调用工具类

     ExcelToPdfUtil.excelToPdf("原始的Excel文件", "要导出的PDF文件", ".xlsx");

如此,即可很好的实现 Excel 转 PDF。

点赞
收藏
评论区
推荐文章
秋桐 秋桐
1年前
通过Java将PPT转换为PDF
PPT和PDF都是非常实用的文档格式。由于PDF文件更为稳定安全且易于传输或储存,所以当需要共享或打印演示文稿时,可以先将PPT转换成PDF格式再进行操作。下面我将介绍如何通过编程的方法实现该转换,所用到的产品是Java组件FreeSpire.PresentationforJava。该方法只需简单几步操作即可实现,同时也能够维持文档内容格式不变。下面是具体方法和示例代码。
Wesley13 Wesley13
3年前
jacob安装配置完整版
1.如果要操作word用jacob当然是最好的。要操作Excel用poi是最棒的。其他的(ppt,pdf)我还没有研究不清楚。2.jacob好是好不过代码比较复杂。网络上有基于jacob封装好的jar:java2word。不过呢,目前java2word版本是有bug的(bug:用JUnit测试是没有任何问题的,但放在web上测试就出错了)。只好自
kenx kenx
3年前
Java8 新特性 Stream Api 之集合遍历
前言随着java版本的不断更新迭代,java开发也可以变得甜甜的,最新版本都到java11了,但是后面版本也是不在提供商用支持,需要收费,但是java8依然是持续免费更新使用的,后面版本也更新很快眼花缭乱,所以稳定使用还是用java8把既可以体验到新功能,又不需要,烦恼升级带来的bug新特性比较新的的特性就是流Stream,和lambda表达式图上
Easter79 Easter79
3年前
swing内嵌浏览器的开发
原本是公司内部的一个小需求,调研后发现这个挺有意思,基于swing本地代码内嵌浏览器的架构,本地代码几乎可以做任何操作,而swing最不擅长的页面渲染交给浏览器去做,目前java对浏览器的二次开发开源框架并不多,我在找了个jxbrow的收费项目,虽然是个收费项目,但是有办法绕过去他的校验机制(作者的校验机制太烂了),可以很容易的作出类似QQ音乐,金山词霸这
秋桐 秋桐
1年前
通过Java实现Word转PDF
Word转为PDF是非常常见的一种格式转换。通过转换可以将文档以更为稳定的格式进行保存,避免他人随意修改格式和内容。其实Word转PDF并不难,除了直接转换外也可以通过编程的方式来实现。网上相关的教程分享也很多。今天想介绍一个JavaWord组件——Fre
Stella981 Stella981
3年前
Gitlab的基础概念
1、什么是Gitlab?Gitlab是一个开源分布式版本控制系统开发语言:Ruby功能:管理项目源代码、版本控制、代码复用与查找2、Gitlab与Github的不同Github分布式在线代码托管仓库,个人版可直接在线免费使用,企业版收费且需要服务器安装。
Stella981 Stella981
3年前
40 个免费和收费的创意 WordPress 主题
免费创意WordPress主题Imbalance!(http://cdn.designmodo.com/wpcontent/uploads/2011/11/517.jpg"5")(https://www.oschina.net/action/GoToLink?urlhttp%3A%2F%2
Stella981 Stella981
3年前
C#实现基于ffmpeg加虹软的人脸识别
关于人脸识别目前的人脸识别已经相对成熟,有各种收费免费的商业方案和开源方案,其中OpenCV很早就支持了人脸识别,在我选择人脸识别开发库时,也横向对比了三种库,包括在线识别的百度、开源的OpenCV和商业库虹软(中小型规模免费)。百度的人脸识别,才上线不久,文档不太完善,之前联系百度,官方也给了我基于Android的Example,但是不太符合我
Stella981 Stella981
3年前
Linux讲解使用前准备
一、Linux和Windows区别比较WindowsLinux费用收费且很贵Linux免费或少许费用软件与支持数量和质量的优势,不过大部分为收费软件;由微软官方提供支持和服务开源自由软件,用户可以修改定制和再发布,由于基本免费没有资金支持,部分软件质量和体验欠缺;有全球所有的Linux开
秋桐 秋桐
1年前
通过Java程序将Excel转换为PDF文档格式
Excel广泛应用于商业、教育等众多领域,具有丰富的数据处理和分析功能,包括计算、图表、排序、筛选、数据透视表等。在处理大型数据内容时,Excel绝对是最佳工具。但如果要将处理好的数据内容进行保存和传输的话,转换为PDF文档格式或许更加可靠。PDF文档的稳定布局可以避免数据内容被随意更改,即使是在多次传输后也能保证数据的准确性。将Excel转换为PDF的工具有很多。这里我将介绍如何通过编程的方法来实现该功能。以Java代码为例,使用到的产品是FreeSpire.XLSforJava(免费版)。下面是程序环境和示例代码。
天航星
天航星
Lv1
天河有尽后为涯 星海无边前作岸
文章
8
粉丝
0
获赞
0