Apache POI 关注生成的 Excel 文件中的特定单元格

3

你好,我正在使用Apache POI生成Excel文件。 我正在使用XSSFWorkbook格式。 我尝试将焦点集中在所生成的Excel文件的第一个单元格上。

我尝试了以下代码片段。

        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问题。但是这个解决方案对我没有用。有人能帮我吗?
附言:我正在使用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());
}

我认为有一种方法可以用于同一张表格的showInPane()。尝试使用此方法,并在此处查看讨论 http://apache-poi.1045710.n5.nabble.com/RE-How-to-mandate-showing-the-active-cell-when-the-Excel-file-is-first-opened-td2281035.html。 - Bhavesh
@yaswanth:.getPane().xsetTopLeftCell().setTopLeftCell("C1") 不是我建议的,也无法编译。 - Axel Richter
抱歉,那是一个错误。我已经更新了代码。 - yaswanth
@yaswanth:好的,但是现在我无法重现您的行为。使用您的代码片段对我来说可以正常工作,具有默认的“XSSFSheet”。列“A:B”是固定的,可滚动窗格从列“C”开始,并且活动单元格是固定窗格中的“A1”。 - Axel Richter
1个回答

4

很不幸,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();
 }
}

本段内容涉及IT技术,其中使用了基础低级对象的 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
getPane().setTopLeftCell("C1")(我的冻结窗格冻结到B列)似乎不起作用。虽然Excel表格在C列打开,但它没有显示我想要的第一行。 - yaswanth
@yaswanth:我的示例代码按预期工作。如果您有意图不符的代码,则需要查看该代码。请更新您的问题,提供一个最小,完整和可验证的示例 - Axel Richter
@AlexRichter,我已经在问题中更新了我的代码。非常感谢您的帮助! - yaswanth
@yaswanth:是的,如果固定窗格中不包含任何行,就像这个例子一样,那么在.getPane().setTopLeftCell中设置行似乎没有意义。然后必须在SheetView中设置顶行。请参见我的补充说明。 - Axel Richter
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接