繁体   English   中英

如何在HSSF apache poi(JAVA)上使用相对参考克隆功能

[英]How to Clone Function with relative Reference on HSSF apache poi (JAVA)

我正在尝试制作一个导出Excel,并且我需要在Excel中提供一些用于计数的公式,但是我有一个来自数据库的数据,它将不止一个。 所以我想将该公式克隆到下一个数据。

它运行良好,但是参考单元格无法更改为下一个单元格,就像我们尝试从excel复制单元格一样

cellOne[data].setCellFormula(celltwo[data].getCellFormula());

我想将计数从data1复制到data2

在我看来,最佳实践实际上不是使用公式字符串来更新公式引用,而是实际上使用了FormulaParser 好处是,只要FormulaParser知道,实际上所有可能的公式都可以更新。 操作公式字符串容易导致问题。 例如,公式模板(例如"SUM(H%d;I%d)"具有%d作为要替换的变量。 但是百分号在某些公式中也可能是不变的。

apache poi具有可以使用的FormulaParser Apache POI更新复制时的公式引用中,我已经针对XSSF展示了这一点。

由于该问题是关于HSSF我将显示一个String copyFormula(Sheet sheet, String formula, int coldiff, int rowdiff)方法,该方法适用于SS作为用于HSSF以及用于XSSF

import java.io.FileOutputStream;

import org.apache.poi.ss.formula.*;
import org.apache.poi.ss.formula.ptg.*;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFEvaluationWorkbook;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.usermodel.HSSFEvaluationWorkbook;

public class ExcelCopyFormula {

 private static String copyFormula(Sheet sheet, String formula, int coldiff, int rowdiff) {

  Workbook workbook = sheet.getWorkbook();
  EvaluationWorkbook evaluationWorkbook = null;
  if (workbook instanceof HSSFWorkbook) {
   evaluationWorkbook = HSSFEvaluationWorkbook.create((HSSFWorkbook) workbook);
  } else if (workbook instanceof XSSFWorkbook) {
   evaluationWorkbook = XSSFEvaluationWorkbook.create((XSSFWorkbook) workbook);
  }

  Ptg[] ptgs = FormulaParser.parse(formula, (FormulaParsingWorkbook)evaluationWorkbook, 
   FormulaType.CELL, sheet.getWorkbook().getSheetIndex(sheet));

  for (int i = 0; i < ptgs.length; i++) {
   if (ptgs[i] instanceof RefPtgBase) { // base class for cell references
    RefPtgBase ref = (RefPtgBase) ptgs[i];
    if (ref.isColRelative())
     ref.setColumn(ref.getColumn() + coldiff);
    if (ref.isRowRelative())
     ref.setRow(ref.getRow() + rowdiff);
   }
   else if (ptgs[i] instanceof AreaPtgBase) { // base class for range references
    AreaPtgBase ref = (AreaPtgBase) ptgs[i];
    if (ref.isFirstColRelative())
     ref.setFirstColumn(ref.getFirstColumn() + coldiff);
    if (ref.isLastColRelative())
     ref.setLastColumn(ref.getLastColumn() + coldiff);
    if (ref.isFirstRowRelative())
     ref.setFirstRow(ref.getFirstRow() + rowdiff);
    if (ref.isLastRowRelative())
     ref.setLastRow(ref.getLastRow() + rowdiff);
   }
  }

  formula = FormulaRenderer.toFormulaString((FormulaRenderingWorkbook)evaluationWorkbook, ptgs);
  return formula;
 }

 public static void main(String[] args) throws Exception {

  //String type = "XSSF";
  String type = "HSSF";

  try (Workbook workbook = ("XSSF".equals(type))?new XSSFWorkbook():new HSSFWorkbook(); 
       FileOutputStream out = new FileOutputStream(("XSSF".equals(type))?"Excel.xlsx":"Excel.xls") ) {

   Sheet sheet = workbook.createSheet();

   for (int r = 2 ; r < 10; r++) {
    Row row = sheet.createRow(r);
    for (int c = 2 ; c < 5; c++) {
     Cell cell = row.createCell(c);
     if (r == 2) {
      if (c == 2) cell.setCellValue("No");
      if (c == 3) cell.setCellValue("Number One");
      if (c == 4) cell.setCellValue("Number Two");
     } else {
      if (c == 2) cell.setCellValue("data" + (r-2));
      if (c == 3) cell.setCellValue(r*c);
      if (c == 4) cell.setCellValue(r*c);
     }
    }
   }

   for (int r = 2 ; r < 10; r++) {
    Row row = sheet.getRow(r);
    Cell cell = row.createCell(5);
    String formula = "D4+E4";
    if (r == 2) cell.setCellValue("Formula");
    else cell.setCellFormula(copyFormula(sheet, formula, 0, r-3));
   }

   for (int r = 2 ; r < 10; r++) {
    Row row = sheet.getRow(r);
    Cell cell = row.createCell(6);
    String formula = "G4+F5";
    if (r == 2) cell.setCellValue("Cumulative");
    else if (r == 3) cell.setCellFormula("F4");
    else cell.setCellFormula(copyFormula(sheet, formula, 0, r-4));
   }

   workbook.getCreationHelper().createFormulaEvaluator().evaluateAll();
   workbook.write(out);

  }
 }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM