为 XSSFSheet 设置顶行和左列

Set top row and left column for an XSSFSheet

我试图确保打开文件时 XLSX sheet 位于左上角。

XSSFSheet有一个getTopCol() and a getLeftCol()方法,但是没有setter.

XSSFSheet.showInPane(int, int) 确实有效,但前提是窗格被冻结或拆分。

    PaneInformation pane = sheet.getPaneInformation();
    if (pane == null) {
        // FIXME doesn't work when there is no pane
        sheet.showInPane(CellAddress.A1.getRow(), CellAddress.A1.getColumn());
    } else {
        // OK
        sheet.showInPane(pane.getHorizontalSplitPosition(), pane.getVerticalSplitPosition());
    }

我试图查看可以从 XSSFSheet class 访问的内容,但所有底层方法都是私有的。

有人知道将 sheet 的视图重置为左上角单元格的方法吗?

好像直接用POI对象没有这样的设置。但是 CTWorksheet 是可能的。 http://grepcode.com/file/repo1.maven.org/maven2/org.apache.poi/ooxml-schemas/1.1/org/openxmlformats/schemas/spreadsheetml/x2006/main/CTWorksheet.java#CTWorksheet

...
((XSSFSheet)sheet).getCTWorksheet().getSheetViews().getSheetViewArray(0).setTopLeftCell("D10");
...

获取此类信息的最佳方法是直接使用 Excel 创建一个简单的文件。然后将其保存为 *.xlsx。然后解压缩此文件并查看 /xl/worksheets/sheet1.xml。你会发现:

...
<sheetViews>
 <sheetView workbookViewId="0" tabSelected="true" topLeftCell="D10"/>
</sheetViews>
...

要对此添加更多背景信息:

如果您查看 getTopRow() and getLeftCol() 的各自实现,它们都从 CTSheetView 的实例中获取它们的值(通过两种不同的方式,我想这并非完全有意)。

相比之下,showInPane() is based on a CTPane which is a data structure that lives one level below a CTSheetView. According to ECMA-376(第 3904 页)这样的 CTPane 是可选的(即您不必对 CTSheetView 应用 "split")。

然而,我仍然怀疑以下内容:showInPane()(通过 getPane())实际上确实会尝试在存在 none 的情况下创建一个新窗格,但是.然后在这个新窗格上调用 setTopLeftCell() - 根据 ECMA-376(第 1657 页),它仅适用于 右下窗格 。不过,新窗格的默认类型是 左上角(有关可用窗格列表,请参阅该规范的第 2460 页)。

这意味着:

  • 那个可怕的 ECMA-376 规范中可能有错误。因此,对于所有窗格类型,实际上都可以设置左上角的单元格。
  • POI 可能在 getPane() 方法的某处包含一个错误,该错误阻止它实际将新窗格插入 sheet 视图。

...对于如何解决这个问题的务实解决方案,您应该坚持 Axel Richter 的回答。这将直接在 CTSheetView 上设置可见单元格,这很可能是您想要的。