Java POI excel单元格计算的三种方式

Maven环境

  <!-- https://mvnrepository.com/artifact/org.apache.poi/poi -->
  <dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>5.2.2</version>
  </dependency>
  <!-- https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml -->
  <dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>5.2.2</version>
  </dependency>

1、方式一:填写数字计算

/**
 * excel单元格公式计算
 * <pre>
 *     workbook三种文件格式的导出对比
 *     https://blog.csdn.net/sufu1065/article/details/115301974
 * </pre>
 */
public static void setCellFormulaCalc1() throws IOException {
    /*
     * POI关于 工作簿的三个对象
     *      1. new HSSFWorkbook(): 格式为office 2003专用格式,即.xls,优点是导出数据速度快,但是最多65536行数据,行数多了就会报错
     *      2. new XSSFWorkbook(): 导出的文件格式为office 2007专用格式,即.xlsx,优点是导出的数据不受行数限制,缺点导出速度慢
     *      3. new SXSSFWorkbook(): SXSSF 是 XSSF API的兼容流式扩展,主要解决当使用 XSSF 方式导出大数据量时,内存溢出的问题,支持导出大批量的excel数据
     */
    SXSSFWorkbook workbook = new SXSSFWorkbook();
    SXSSFSheet sheet = workbook.createSheet("excel单元格公式计算");

    SXSSFRow row1 = sheet.createRow(0);

    // 第一列
    SXSSFCell cell1 = row1.createCell(0);
    // 不推荐使用指定单元格的类型
    // cell1.setCellType(CellType.FORMULA); // 公式类型:在直接写计算方式的时候不能指定CellType.FORMULA类型,否则会报类型非法的错误
    cell1.setCellFormula("2+3*4"); // 计算公式 结果14

    FileOutputStream outputStream = new FileOutputStream("D:/temp/Excel单元格公式计算.xlsx");
    workbook.write(outputStream);
    outputStream.close();
    workbook.close();
}

直接由数字计算来最终结果
image.png

2、方式二:excel函数计算(示例SUM求和函数)

/**
 * excel单元格公式计算
 * <pre>
 *     workbook三种文件格式的导出对比
 *     https://blog.csdn.net/sufu1065/article/details/115301974
 * </pre>
 */
public static void setCellFormulaCalc1() throws IOException {
    /*
     * POI关于 工作簿的三个对象
     *      1. new HSSFWorkbook(): 格式为office 2003专用格式,即.xls,优点是导出数据速度快,但是最多65536行数据,行数多了就会报错
     *      2. new XSSFWorkbook(): 导出的文件格式为office 2007专用格式,即.xlsx,优点是导出的数据不受行数限制,缺点导出速度慢
     *      3. new SXSSFWorkbook(): SXSSF 是 XSSF API的兼容流式扩展,主要解决当使用 XSSF 方式导出大数据量时,内存溢出的问题,支持导出大批量的excel数据
     */
    SXSSFWorkbook workbook = new SXSSFWorkbook();
    SXSSFSheet sheet = workbook.createSheet("excel单元格公式计算");

    SXSSFRow row1 = sheet.createRow(0);

    // 第一列
    SXSSFCell cell1 = row1.createCell(0);
    // 不推荐使用指定单元格的类型
    // cell1.setCellType(CellType.FORMULA); // 公式类型:在直接写计算方式的时候不能指定CellType.FORMULA类型,否则会报类型非法的错误
    cell1.setCellFormula("2+3*4"); // 计算公式 结果14

    // 第二列
    SXSSFCell cell2 = row1.createCell(1);
    cell2.setCellValue(10);

    // 第三列
    SXSSFCell cell3 = row1.createCell(2);
//        cell3.setCellType(CellType.FORMULA);
    // 计算A列1行+B列1行的和
    cell3.setCellFormula("SUM(A1,B1)");

    // 第四列
    SXSSFCell cell4 = row1.createCell(3);
//        cell3.setCellType(CellType.FORMULA);
    // 计算A列1行+B列1行的和+C列1行的和
    cell4.setCellFormula("SUM(A1,B1,C1)");

    FileOutputStream outputStream = new FileOutputStream("D:/temp/Excel单元格公式计算.xlsx");
    workbook.write(outputStream);
    outputStream.close();
    workbook.close();
}

image.png
image.png

3、方式三:按指定单元格计算

/**
 * 直接指定列名的计算方式
 */
public static void calcCellByCellName() throws IOException {
    SXSSFWorkbook workbook = new SXSSFWorkbook();
    SXSSFSheet sheet = workbook.createSheet("excel指定列计算公式");

    int rowIndex = 0, rowNum = 1;
    int cellIndex1 = 0, cellIndex2 = 1, cellIndex3 = 2, cellIndex4 = 3; // 1-4列, 第四列为前三列计算结果 cellIndex1 - cellIndex2 + cellIndex3

    // 创建行列并设置值和计算公式
    SXSSFRow row = sheet.createRow(rowIndex);
    SXSSFCell cell1 = row.createCell(cellIndex1);
    cell1.setCellValue(10);

    SXSSFCell cell2 = row.createCell(cellIndex2);
    cell2.setCellValue(2);

    SXSSFCell cell3 = row.createCell(cellIndex3);
    cell3.setCellValue(4);

    SXSSFCell cell4 = row.createCell(cellIndex4);
    // ====> A1 - B1 + C1
    //cell4.setCellFormula((excelIndexToStr(cellIndex1) + rowNum) + "-" + (excelIndexToStr(cellIndex2) + rowNum) + "+" + (excelIndexToStr(cellIndex3) + rowNum));
    cell4.setCellFormula("A1-B1+C1");

    FileOutputStream outputStream = new FileOutputStream("D:/temp/Excel指定列计算公式.xlsx");
    workbook.write(outputStream);
    outputStream.close();
    workbook.close();
}

image.png

4、求和函数升级计算:求指定行一行数据的和,结果填到最后

/**
 * 单元格列尾求和
 */
public static void calcCellEndSum() throws IOException {
    SXSSFWorkbook workbook = new SXSSFWorkbook();
    SXSSFSheet sheet = workbook.createSheet("excel单元格列尾求和计算");

    // 定义:定义列数据
    int[] dataList = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

    // 第一行定义为列名
    SXSSFRow row1 = sheet.createRow(0);
    for (int cellIndex = 0; cellIndex <= dataList.length; cellIndex++) {
        SXSSFCell cell = row1.createCell(cellIndex);
        if (cellIndex == dataList.length) {
            cell.setCellValue("合计");
        } else {
            cell.setCellValue("数据" + (cellIndex + 1));
        }
    }

    SXSSFRow row2 = sheet.createRow(1);
    // 第二行为数据
    for (int cellIndex = 0; cellIndex < dataList.length; cellIndex++) {
        SXSSFCell cell = row2.createCell(cellIndex);
        cell.setCellValue(dataList[cellIndex]);
    }
    // 计算指定行的数据,结果填到最后
    lastCellSumByRow(row2);


    FileOutputStream outputStream = new FileOutputStream("D:/temp/Excel单元格列尾求和计算.xlsx");
    workbook.write(outputStream);
    outputStream.close();
    workbook.close();
}

/**
 * 指定行的末列求和: 填写计算结果
 */
public static void lastCellSumByRow(SXSSFRow row) {
    short lastCellNum = row.getLastCellNum();
    // 统计一行数据的求和结果
    List<String> sumCell = new ArrayList<>();
    for (int index = 0; index < lastCellNum; index++) {
        String str = excelIndexToStr(index);
        // A+行号
        int rowNum = row.getRowNum() + 1;
        System.err.println(str + rowNum);
        sumCell.add(str + rowNum);
    }

    // 最后一列求和
    SXSSFCell lastCell = row.getCell(lastCellNum);
    if (lastCell == null) {
        lastCell = row.createCell(lastCellNum);
    }
    lastCell.setCellFormula("SUM(" + StringUtils.join(sumCell, ",") + ")");
}

/**
 * https://blog.csdn.net/leeo_may/article/details/123680350
 * 列索引转换为A,B,C...
 * <pre>
 *     如:cellIndex=0 --> A
 *     如:cellIndex=1 --> B
 *     如:cellIndex=25 --> Z
 *     如:cellIndex=26 --> AB
 * </pre>
 *
 * @param cellIndex Excel列索引
 */
private static String excelIndexToStr(int cellIndex) {
    // 转26进制 0-25
    // int calculateValue = value - 1; (value = cellIndex + 1)
    int calculateValue = cellIndex; // 本身传进来的就是列索引0-25,的26进制
    // 取高位
    int high = calculateValue / 26;
    // 取低位
    int low = calculateValue % 26;
    // 低位可直接取出对应的字母
    String transStr = String.valueOf((char) (low + 65));
    if (high > 0) {
        // 高位递归取出字母
        transStr = excelIndexToStr(high) + transStr;
    }
    return transStr;
}

image.png

参考链接

Java实现Excel列号转字母_幼稚园保安的博客-CSDN博客
Java中操作Excel的3种方法,太好用了!_sufu1065的博客-CSDN博客

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Java POI是一个用于操作Microsoft Office格式文件的开源库,在处理Excel文件时可以使用它来实现单元格的合并和数据读取。下面是一个使用Java POI来合并单元格并读取数据的示例: 1. 导入Java POI的相关库: ```java import org.apache.poi.ss.usermodel.*; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import java.io.FileInputStream; import java.io.IOException; ``` 2. 定义一个方法来读取Excel文件: ```java public static void readExcel(String filePath) { try { FileInputStream fileInputStream = new FileInputStream(filePath); Workbook workbook = new XSSFWorkbook(fileInputStream); Sheet sheet = workbook.getSheetAt(0); // 循环遍历每一行 for (Row row : sheet) { // 循环遍历每一列 for (Cell cell : row) { // 判断单元格的合并状态 if (cell.getCellType() == CellType.STRING && cell.getCellStyle().getAlignment() == HorizontalAlignment.CENTER) { // 获取合并区域的开始行、结束行、开始列、结束列 int firstRow = sheet.getMergedRegion(cell.getColumnIndex(), cell.getRowIndex()).getFirstRow(); int lastRow = sheet.getMergedRegion(cell.getColumnIndex(), cell.getRowIndex()).getLastRow(); int firstColumn = sheet.getMergedRegion(cell.getColumnIndex(), cell.getRowIndex()).getFirstColumn(); int lastColumn = sheet.getMergedRegion(cell.getColumnIndex(), cell.getRowIndex()).getLastColumn(); // 获取合并区域的数据 String mergedData = sheet.getRow(firstRow).getCell(firstColumn).getStringCellValue(); // 打印合并区域的数据 System.out.println(mergedData); } } } workbook.close(); fileInputStream.close(); } catch (IOException e) { e.printStackTrace(); } } ``` 3. 调用readExcel方法来读取Excel文件: ```java public static void main(String[] args) { readExcel("excelFile.xlsx"); } ``` 以上就是使用Java POI来合并单元格并读取数据的一个简单示例。通过判断单元格的合并状态,可以获取到合并区域的数据。根据具体的需可以进一步处理合并区域的数据。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小白说(๑• . •๑)

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值