几年前在这里问了同样的问题: how to remove all formulas from an excel sheet by java POI api?
然而,当时没有得到答案对我有用。
我有一个带有几个大表的工作簿,并希望循环所有单元格以用字符串替换单元格内容。问题是,许多单元格包含我必须先摆脱的公式。 public lineVistaChartOptions:any = {
responsive: true,
annotation:{
drawTime: 'afterDatasetsDraw', // (default)
events: ['click'],
dblClickSpeed: 350, // ms (default)
annotations: {
type: 'line',
drawTime: 'afterDatasetsDraw',
id: 'a-line-1',
mode: 'horizontal',
// ID of the scale to bind onto
scaleID: 'y-axis-0',
value: 50,
endValue: 100,
borderColor: 'red',
borderWidth: 2,
borderDash: [2, 2],
borderDashOffset: 1,
label: {
backgroundColor: 'rgba(0,0,0,0.8)',
fontFamily: "sans-serif",
fontSize: 12,
fontStyle: "bold",
fontColor: "#fff",
xPadding: 0,
yPadding: 0,
cornerRadius: 6,
position: "center",
xAdjust: 0,
yAdjust: 0,
enabled: true,
content: "Test label"
}
}
}
和cell.setCellFormula(null)
(也不是cell.setCellType(CellType.STRING)
)都不令人满意,因为删除数组公式的基础过程需要很长时间,并使整个作业太慢。
以下工作但留下了损坏的Excel工作簿,只能在第一次修复步骤时打开:
BLANK
Method m = XSSFCell.class.getDeclaredMethod("setBlank");
m.setAccessible(true);
是否有任何其他快速和清洁的方法可以将某些单元格设置为空白,无论是否有任何公式?
答案 0 :(得分:1)
出现损坏的工作簿的原因是/xl/calcChain.xml
中存储了一个计算链。删除公式的常规慢速方法将更新此计算链。但是,正如您已经发现的那样,它们也试图仅用于删除单个公式,而不是全部。所以他们必须小心地删除部分数组公式,这会使它们变慢。
但是如果真的所有公式都要删除,那么这种谨慎是不必要的,然后只需删除整个/xl/calcChain.xml
。
示例:
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.*;
import org.apache.poi.xssf.model.CalculationChain;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.STCellFormulaType;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import org.apache.poi.POIXMLDocumentPart;
import java.lang.reflect.Method;
class ExcelRemoveFormulasAndCalcChain {
private static void removeCalcChain(XSSFWorkbook workbook) throws Exception {
CalculationChain calcchain = workbook.getCalculationChain();
Method removeRelation = POIXMLDocumentPart.class.getDeclaredMethod("removeRelation", POIXMLDocumentPart.class);
removeRelation.setAccessible(true);
removeRelation.invoke(workbook, calcchain);
}
public static void main(String[] args) throws Exception {
XSSFWorkbook workbook = (XSSFWorkbook)WorkbookFactory.create(new FileInputStream("Test.xlsx"));
for (Sheet sheet : workbook) {
for (Row row : sheet) {
for (Cell cell : row) {
XSSFCell xssfcell = (XSSFCell)cell;
if (xssfcell.getCTCell().isSetF() && xssfcell.getCTCell().getF().getT() != STCellFormulaType.DATA_TABLE) {
xssfcell.getCTCell().unsetF();
}
}
}
}
removeCalcChain(workbook);
workbook.write(new FileOutputStream("Test_1.xlsx"));
workbook.close();
}
}
这应该删除所有公式,让所有单元格只包含值和样式。
答案 1 :(得分:0)
我想我能够找到如何删除某些单元格范围内的公式。 我注意到,如果我删除带有链接的工作表第一个公式,它会被快速删除。 如果我交换删除公式和删除工作表,则需要很多时间。 因此,如果我们创建一个工作表,使用指向它的链接重写所有公式,然后删除工作表,公式将被快速删除(设置带有不存在工作表链接的公式不起作用)。 15k+ 行需要几秒钟。这是实验:
File fReport = new File(".xlsx");
XSSFWorkbook book = new XSSFWorkbook(new FileInputStream(fReport));
XSSFSheet sheet = book.getSheet("");
XSSFSheet dummy = book.createSheet("dummy");
int lastRow = sheet.getLastRowNum();
for (int i = 8; i <= lastRow; i++) {
XSSFRow rowToClean = sheet.getRow(i);
XSSFCell cell = rowToClean.getCell(2);
System.out.println(i);
if (cell != null) {
cell.setCellFormula("'dummy'!A1");
}
}
book.removeSheetAt(book.getSheetIndex(dummy));
for (int i = 8; i <= lastRow; i++) {
XSSFRow rowToClean = sheet.getRow(i);
XSSFCell cell = rowToClean.getCell(2);
System.out.println(i);
if (cell != null) {
cell.removeFormula();
}
}
book.write(new FileOutputStream(fReport));
book.close();