Java Apache POI从工作簿中删除CellStyle

Java Apache POI从工作簿中删除CellStyle,java,apache-poi,Java,Apache Poi,使用ApachePOI。。。我使用了workbook.CreateCellStyle(),如果过了一段时间我需要删除创建的CellStyle。。。如何将其从工作簿中删除?我可以看到,即使没有使用,它仍然保留着 我需要的是类似于workbook.deleteCellStyle(cellStyle.getIndex())的东西 从来源判断,以下方法删除未使用的单元格样式: org.apache.poi.hssf.usermodel.HSSFOptimiser.optimiseCellStyles(H

使用ApachePOI。。。我使用了workbook.CreateCellStyle(),如果过了一段时间我需要删除创建的CellStyle。。。如何将其从工作簿中删除?我可以看到,即使没有使用,它仍然保留着


我需要的是类似于workbook.deleteCellStyle(cellStyle.getIndex())的东西

从来源判断,以下方法删除未使用的单元格样式:

org.apache.poi.hssf.usermodel.HSSFOptimiser.optimiseCellStyles(HSSFWorkbook)

获取单元格并将“无”设置为“样式”可能会起作用:

HSSFRow hr= workBook.getSheet("SheetName").getRow(rowIndex);
HSSFCell hc=hr.getCell(cellIndex);
hc.setCellStyle(null);

请尝试此方法,这可能对您有用。

您可以通过将任何所需的单元格样式的数据复制到新创建的工作簿来解决此问题。幕后的单元格样式“生存”似乎有问题,或未经深思熟虑。

截至,HSSFOOptimiser还将删除未使用的样式,除了删除重复的单元格样式之外

因此,请抓紧最近的夜间构建/svn签出构建(或者等待一个月左右3.9-beta1的发布!),然后执行以下操作:

NPOIFSFileSystem poifs = new NPOIFSFileSystem(new File("/path/to/excel/file.xls"));
HSSFWorkbook wb = new HSSFWorkbook(poifs.getRoot());
HSSFOptimiser.optimiseCellStyles(wb);

FileOutputStream fout = new FileoutputStream("optimised.xls");
wb.write(fout);
fout.close()
之后,
optimsed.xls
将不包含重复的单元格样式,也不包含未使用的单元格样式。(如果文件尚未存在,您可以轻松地将优化步骤放在创建文件的末尾)


注意-HSSFOOptimiser方法仅适用于.xls文件,不适用于XSSF.xlsx文件。不需要太多的工作就可以推广该方法,但目前它只是HSSF….

当前源代码中没有直接的方法:

以下是创建样式的方式:

public HSSFCellStyle createCellStyle()
{
    ...
    ExtendedFormatRecord xfr = workbook.createCellXF();
    short index = (short) (getNumCellStyles() - 1);
    HSSFCellStyle style = new HSSFCellStyle(index, xfr, this);
    return style;
}

和(在内部工作簿中)

并将工作簿.createCellXF()解析为:

public ExtendedFormatRecord createCellXF() {
    ExtendedFormatRecord xf = createExtendedFormat();

    records.add(records.getXfpos()+1, xf);
    records.setXfpos( records.getXfpos() + 1 );
    numxfs++;
    return xf;
}
因此,从HSSF工作手册中可以调用:

InternalWorkbook getWorkbook() {
    return workbook;
}
然后在InternalWorkbook对象上:

public ExtendedFormatRecord getExFormatAt(int index) {
    int xfptr = records.getXfpos() - (numxfs - 1);

    xfptr += index;
    ExtendedFormatRecord retval =
    ( ExtendedFormatRecord ) records.get(xfptr);

    return retval;
}

public void removeExFormatRecord(ExtendedFormatRecord rec) {
    records.remove(rec); // this updates XfPos for us
    numxfs--;
}
简而言之,从最上面的工作簿开始,类似以下内容:

 InternalWorkbook w = workbook.getWorkbook();
 ExtendedFormatRecord record = w.getExFormatAt(index);
 w.removeExFormatRecord(record);

这一切都非常可怕:)

看起来它确实应该完成任务。。。但是运行它并不能真正起到任何作用!稍后我将再次尝试调试它。样式仍将存储在文件中。经过几天的搜索,我声称没有直接的方法可以使用ApachePOI从工作簿中删除样式。这不是一个好建议。如果书中有3个或更多重数据,OP只需要删除一个单元格怎么办?什么是“3个或更多重数据”?而且:他不是在删除单元格,他想删除未引用的单元格样式。一个变通办法就是一个变通办法,这是一个变通办法,而不是一个解决方案,所以:那又怎样。如果你有,让我们知道。cellstyle在复制细胞值的同时,其存活率是零。这些款式都将被淘汰。这意味着我需要在新工作簿中创建新样式。cellstyle经理可以帮我完成这项任务。不过,我担心的表现@路易吉:你说得对。在某些情况下,所有样式都不会被删除,但我仍然必须确保没有未使用/重复的样式。这是我(过于笼统)的答案+1的有用和超级版本。这种方法只解决了一半的问题,没有触及OOXML格式(*.xlsx文件)。另一方面,转换xlsx->xls->xlsx应该没有那么难。我应该试试看性能如何。@Gagravarr有没有办法为Xlsx做到这一点…?@PrasannaKumar没有,仍然需要有人自愿基于HSSF编写XSSF版本one@Gagravarr日期数据类型呢。。。?每次我们需要在引用的文件中采用新的单元格样式并将其与现有单元格样式(创建新的始终的原因)克隆…它超过了始终…是否有任何方法可以防止这种情况发生我认为这可能会导致我出现问题。我只是快速查看了ExtendedFormatRecord,在我看来,样式和单元格都是ExtendedFormatRecords。如果我在这个索引中找出正确的样式数,我相信我可能能够删除它。但是,我担心从单元格到(删除的)样式的所有引用都会被破坏……您也需要修复引用,否则在删除时混乱XFs的顺序会导致崩溃。查看HSSFOptimiser,了解需要执行的操作!虽然这并不是我问题的完整答案,但这个简单的poi源代码副本为我指明了正确的方向。谢谢对结果是getExFormatAt()的索引号与getCellStyleAt()的索引号相同。
public ExtendedFormatRecord getExFormatAt(int index) {
    int xfptr = records.getXfpos() - (numxfs - 1);

    xfptr += index;
    ExtendedFormatRecord retval =
    ( ExtendedFormatRecord ) records.get(xfptr);

    return retval;
}

public void removeExFormatRecord(ExtendedFormatRecord rec) {
    records.remove(rec); // this updates XfPos for us
    numxfs--;
}
 InternalWorkbook w = workbook.getWorkbook();
 ExtendedFormatRecord record = w.getExFormatAt(index);
 w.removeExFormatRecord(record);