【问题标题】:Apache POI Focus on a particular cell in generated excel fileApache POI 专注于生成的 excel 文件中的特定单元格
【发布时间】:2025-11-23 16:30:01
【问题描述】:

您好,我正在使用 apache poi 生成 excel 文件。我正在使用 XSSFWorkbook 格式。我正在尝试将注意力集中在生成的 excel 文件的第一个单元格上。

我试过下面的代码sn-p。

        try {
                Sheet sheet = workbook.getSheetAt(0);
                workbook.setActiveSheet(0);
                Cell cell = sheet.getRow(0).getCell(0);
                cell.setAsActiveCell();
                sheet.setActiveCell(cell.getAddress());
                sheet.showInPane(0, 0);
            } catch (IllegalArgumentException e) {
                LOGGER.error("Failed to set active sheet and cell.", e);
            }

我也看过这个SO question。该解决方案似乎对我不起作用。有人可以帮我吗?

P.S:我使用的是 apache poi 3.15 版。

更新 1:

我还有一个冻结窗格,左上角单元格为 C1。冻结未正确显示。

我试过下面的代码

public void setActiveCell(Workbook workbook, int sheetIndex, int row, int column) {
        Sheet sheet = workbook.getSheetAt(sheetIndex);
        CellAddress cellAddress = new CellAddress(row, column);

        sheet.createFreezePane(2, 0);
        ((XSSFSheet) sheet).getCTWorksheet().getSheetViews().getSheetViewArray(0).getPane()
            .setTopLeftCell("C1");
        ((XSSFSheet) sheet).setActiveCell(cellAddress);

//        ((XSSFSheet) sheet).getCTWorksheet().getSheetViews().getSheetViewArray(0)
//            .setTopLeftCell(cellAddress.formatAsString());
//        ((XSSFSheet) sheet).setActiveCell(cellAddress);
}

我将上述代码称为setActiveCell(workbook, 0, 0, 0);。可以确保工作簿不为空,并且至少包含一张工作表。上面的代码既没有显示 C1 单元格(创建的窗格的左上角单元格),也没有显示 A1 单元格(活动单元格集)。

更新 2:

根据@AlexRichter 的回答,以下代码适用于我:

public void setActiveCell(Workbook workbook, int sheetIndex, int row, int column) {
        Sheet sheet = workbook.getSheetAt(sheetIndex);
        CellAddress cellAddress = new CellAddress(row, column);

        sheet.createFreezePane(2, 0);
        ((XSSFSheet) sheet).getCTWorksheet().getSheetViews().getSheetViewArray(0).getPane()
            .setTopLeftCell("C1");

        ((XSSFSheet) sheet).getCTWorksheet().getSheetViews().getSheetViewArray(0)
            .setTopLeftCell(cellAddress.formatAsString());
}

【问题讨论】:

  • 我认为有一种方法可以用于同一张 sheet.showInPane() 。试试这个方法,也可以在这里查看这个讨论apache-poi.1045710.n5.nabble.com/…
  • @yaswanth: .getPane().xsetTopLeftCell().setTopLeftCell("C1") 不是我建议的,也不会编译。
  • 抱歉打错了。我已经更新了代码
  • @yaswanth:好的,但现在我无法重现你的行为。使用您的代码 sn-p 按预期对我有用,默认 XSSFSheet。列A:B 是固定的,可滚动窗格以列C 开头,活动单元格是固定窗格中的A1

标签: java excel apache-poi


【解决方案1】:

很遗憾,XSSFSheet.showInPane 有问题。

以下对我有用:

import org.apache.poi.xssf.usermodel.*;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.*;

import java.io.FileOutputStream;

class TopLeftCell {

 public static void main(String[] args) throws Exception{
  Workbook wb = new XSSFWorkbook();

  Sheet sheet = wb.createSheet("new sheet");

  ((XSSFSheet)sheet).getCTWorksheet().getSheetViews().getSheetViewArray(0).setTopLeftCell("D10");
  ((XSSFSheet)sheet).setActiveCell(new CellAddress("E11"));

  wb.write(new FileOutputStream("TopLeftCell.xlsx"));
  wb.close();
 }
}

它使用来自基本低级对象的setTopLeftCell

如果你有窗格,那么你必须为你需要的窗格设置 TopLeftCell。示例:

import org.apache.poi.xssf.usermodel.*;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.*;

import java.io.FileOutputStream;

class TopLeftCell {

 public static void main(String[] args) throws Exception{
  Workbook wb = new XSSFWorkbook();

  Sheet sheet = wb.createSheet("new sheet");
/*
  ((XSSFSheet)sheet).getCTWorksheet().getSheetViews().getSheetViewArray(0).setTopLeftCell("D10");
  ((XSSFSheet)sheet).setActiveCell(new CellAddress("E11"));
*/

  sheet.createFreezePane(2, 2); //C3 is top left cell of the scrollable pane
  ((XSSFSheet)sheet).getCTWorksheet().getSheetViews().getSheetViewArray(0).getPane().setTopLeftCell("C3");
  ((XSSFSheet)sheet).setActiveCell(new CellAddress("A1"));

  wb.write(new FileOutputStream("TopLeftCell.xlsx"));
  wb.close();
 }
}

如果固定窗格不包含行,则似乎存在异常。然后在.getPane().setTopLeftCell 中设置行是没有意义的。那么顶行必须直接设置在SheetView的TopLeftCell中。

例子:

import org.apache.poi.xssf.usermodel.*;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.*;

import java.io.FileOutputStream;

class TopLeftCell {

 public static void main(String[] args) throws Exception{
  Workbook wb = new XSSFWorkbook();

  Sheet sheet = wb.createSheet("new sheet");

  sheet.createFreezePane(2, 0); //C1 is top left cell of the scrollable pane.
  //But if the fixed pane contains no rows, as in this example, then setting the row in 
  //getPane().setTopLeftCell is meaningless. Then the top row must be set in the SheetView.
  //Example: Row 6 shall be the top row:
  ((XSSFSheet)sheet).getCTWorksheet().getSheetViews().getSheetViewArray(0).setTopLeftCell("A6");
  ((XSSFSheet)sheet).getCTWorksheet().getSheetViews().getSheetViewArray(0).getPane().setTopLeftCell("C1");
  ((XSSFSheet)sheet).setActiveCell(new CellAddress("C6"));

  wb.write(new FileOutputStream("TopLeftCell.xlsx"));
  wb.close();
 }
}

【讨论】:

  • 非常感谢您的解决方法。我还有一个问题。我在第二列和第二行有一个冻结窗格。虽然我可以看到活动单元格为 (0,0)(我的意图),但冻结窗格将 excel 表移动到右侧,显示第 25 列。意思是我可以看到第一行和第一列。我可以看到 Excel 表,直到第二列。之后我看到第 25 列。你能帮我让冻结窗格按原样显示 Excel 工作表而不移动吗?
  • @yaswanth:这正是XSSFSheet.showInPane 也有问题的地方。如果您 窗格,则必须为所需的窗格设置 TopLeftCell。但是你不会总是有窗格。请参阅我的补充。
  • getPane().setTopLeftCell("C1") (我的冻结窗格冻结到 B 列)似乎不起作用。虽然 Excel 工作表在 C 列打开,但它没有显示我想要的第一行。
  • @yaswanth:我的示例代码按预期工作。如果您的代码无法按预期工作,那么我们需要查看该代码。请更新您的问题,提供Minimal, Complete, and Verifiable example
  • @AlexRichter,我已经更新了问题中的代码。非常感谢您的帮助!