我如何在 Apache POI 中模拟 Excel 的 "Fill down"?
How do I emulate Excel's "Fill down" in Apache POI?
我有一个模板工作簿,其中包含我使用 Apache POI 填充的 sheet(“所有数据”)。我不知道开始时“所有数据”中需要多少行。
在另一个 sheet(称之为“Calc”)中,我有 4 列包含基于“所有数据”执行操作的公式。我需要在 Calc 中有与“所有数据”中一样多的行,我认为最简单的方法是在模板中有一行,其中包含公式,然后我可以填写 sheet 多次。
因此,在模板中我有:
Col1Header | Col2Header | Col3Header | Col4Header
=+'All data'!F2 | =IF(LEFT(A55,1)="4",'All data'!R2,"") | =IF(LEFT(A55,1)="4",'All data'!O2,"") | =+'All data'!W2
然后我希望能够从第一个公式行“向下填充”,这样我就有 n 行(其中 n 是我在“所有数据”中使用的行数 sheet).
但是,我看不到如何在 Apache POI 中“填写”。这是不可能的事情吗?还是我找错名字了?
是的,另一种方法是通过手动复制比我预期使用的更多的行来简单地更改模板,但那是 (a) 不雅和 (b) 将来会遇到麻烦:-)
我确定一定有更好的方法?
如果这是针对 Office Open XML
工作簿(*.xlsx
、XSSF
)并且使用当前 apache poi 5.0.0
,则可以使用 XSSFSheet.copyRows。默认 CellCopyPolicy
复制公式并调整其中的单元格引用。
示例:
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import java.io.FileInputStream;
import java.io.FileOutputStream;
class ExcelReadCopyRowsAndWrite {
public static void main(String[] args) throws Exception {
String fileIn= "./TestIn.xlsx";
String fileOut= "./TestOut.xlsx";
int n = 10; // 10 rows needed
int fillRowsFromIdx = 1; // start at row 2 (index 1) which is row having the formulas
int fillRowsToIdx = fillRowsFromIdx + n - 1;
try (Workbook workbook = WorkbookFactory.create(new FileInputStream(fileIn));
FileOutputStream out = new FileOutputStream(fileOut)) {
Sheet sheet = workbook.getSheet("Calc"); // do it in sheet named "Calc"
if (sheet instanceof XSSFSheet) {
XSSFSheet xssfSheet = (XSSFSheet) sheet;
for (int i = fillRowsFromIdx; i < fillRowsToIdx; i++) {
xssfSheet.copyRows(i, i, i+1, new CellCopyPolicy());
}
}
workbook.write(out);
}
}
}
copyRows
方法目前仅在 XSSF
中。有关如何复制也适用于 BIFF
工作簿(*.xls
、HSSF
)的示例,请参阅 Apache POI update formula references when copying。
我有一个模板工作簿,其中包含我使用 Apache POI 填充的 sheet(“所有数据”)。我不知道开始时“所有数据”中需要多少行。
在另一个 sheet(称之为“Calc”)中,我有 4 列包含基于“所有数据”执行操作的公式。我需要在 Calc 中有与“所有数据”中一样多的行,我认为最简单的方法是在模板中有一行,其中包含公式,然后我可以填写 sheet 多次。
因此,在模板中我有:
Col1Header | Col2Header | Col3Header | Col4Header
=+'All data'!F2 | =IF(LEFT(A55,1)="4",'All data'!R2,"") | =IF(LEFT(A55,1)="4",'All data'!O2,"") | =+'All data'!W2
然后我希望能够从第一个公式行“向下填充”,这样我就有 n 行(其中 n 是我在“所有数据”中使用的行数 sheet).
但是,我看不到如何在 Apache POI 中“填写”。这是不可能的事情吗?还是我找错名字了?
是的,另一种方法是通过手动复制比我预期使用的更多的行来简单地更改模板,但那是 (a) 不雅和 (b) 将来会遇到麻烦:-)
我确定一定有更好的方法?
如果这是针对 Office Open XML
工作簿(*.xlsx
、XSSF
)并且使用当前 apache poi 5.0.0
,则可以使用 XSSFSheet.copyRows。默认 CellCopyPolicy
复制公式并调整其中的单元格引用。
示例:
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import java.io.FileInputStream;
import java.io.FileOutputStream;
class ExcelReadCopyRowsAndWrite {
public static void main(String[] args) throws Exception {
String fileIn= "./TestIn.xlsx";
String fileOut= "./TestOut.xlsx";
int n = 10; // 10 rows needed
int fillRowsFromIdx = 1; // start at row 2 (index 1) which is row having the formulas
int fillRowsToIdx = fillRowsFromIdx + n - 1;
try (Workbook workbook = WorkbookFactory.create(new FileInputStream(fileIn));
FileOutputStream out = new FileOutputStream(fileOut)) {
Sheet sheet = workbook.getSheet("Calc"); // do it in sheet named "Calc"
if (sheet instanceof XSSFSheet) {
XSSFSheet xssfSheet = (XSSFSheet) sheet;
for (int i = fillRowsFromIdx; i < fillRowsToIdx; i++) {
xssfSheet.copyRows(i, i, i+1, new CellCopyPolicy());
}
}
workbook.write(out);
}
}
}
copyRows
方法目前仅在 XSSF
中。有关如何复制也适用于 BIFF
工作簿(*.xls
、HSSF
)的示例,请参阅 Apache POI update formula references when copying。