[英]Apache POI XSSFWorkbook setSheetOrder not sorting
我正在使用 Apache POI (4.1.1) 修改現有工作簿。 該工作簿包含四張紙。 我通過克隆第二個工作表作為模板,然后將數據寫入新的克隆工作表。 它被克隆了大約六次。 在此過程結束時,我刪除了模板工作表,然后嘗試為所有工作表設置工作表順序:現有工作表(減去模板),然后是我克隆的工作表。 我正在使用 XSSFWorkbook::setSheetOrder 來執行此操作,並且我看到它在調試中更改了索引,但是當我的 Excel 文件實際寫出時,工作表沒有按順序排列。
這是相關的代碼:
// wb is an XSSFWorkbook
wb.removeSheetAt(wb.getSheetIndex("Original Sheet 2")); // Remove the template sheet
wb.setSheetOrder("Original Sheet 1", 0);
for (ReportPresenter presenter : dataMap.values()) {
String sheetTitle = makeSheetTitleFromPresenter(presenter);
int oldIndex = wb.getSheetIndex(wb.getSheet(sheetTitle));
wb.setSheetOrder(sheetTitle, presenter.getAnalysisNumber());
int newIndex = wb.getSheetIndex(wb.getSheet(sheetTitle));
System.out.println(oldIndex + " -> " + newIndex);
}
wb.setSheetOrder("Original Sheet 3", dataMap.size() + 1);
wb.setSheetOrder("Original Sheet 4", dataMap.size() + 2);
我在上面包含了調試 println 以在這里展示我如何知道索引實際上正在使用 setSheetOrder 方法更改為我想要的順序。 但是,當我打開此代碼生成的 Excel 文件時,我的工作表都存在,但它們沒有按照我指定的順序排列。
我真的很感激一些想法! 謝謝你。
無法重現該行為。 請展示一個最小的、可重現的示例,以顯示該行為。
我將提供一個這樣的,它表明它可以正常工作:
像這樣從Execl.xlsx
開始:
然后如下代碼:
import java.io.FileOutputStream;
import java.io.FileInputStream;
import org.apache.poi.xssf.usermodel.*;
public class ExcelSetSheetOrder {
public static void main(String[] args) throws Exception {
java.util.Map<Integer, ReportPresenter> dataMap = new java.util.HashMap<Integer, ReportPresenter>();
dataMap.put(1, new ReportPresenter("New Sheet 1", 1));
dataMap.put(2, new ReportPresenter("New Sheet 2", 2));
dataMap.put(3, new ReportPresenter("New Sheet 3", 3));
dataMap.put(4, new ReportPresenter("New Sheet 4", 4));
dataMap.put(5, new ReportPresenter("New Sheet 5", 5));
dataMap.put(6, new ReportPresenter("New Sheet 6", 6));
try (XSSFWorkbook workbook = new XSSFWorkbook(new FileInputStream("./Excel.xlsx"))) {
workbook.cloneSheet(workbook.getSheetIndex("Original Sheet 2"), dataMap.get(1).getSheetTitle());
workbook.cloneSheet(workbook.getSheetIndex("Original Sheet 2"), dataMap.get(2).getSheetTitle());
workbook.cloneSheet(workbook.getSheetIndex("Original Sheet 2"), dataMap.get(3).getSheetTitle());
workbook.cloneSheet(workbook.getSheetIndex("Original Sheet 2"), dataMap.get(4).getSheetTitle());
workbook.cloneSheet(workbook.getSheetIndex("Original Sheet 2"), dataMap.get(5).getSheetTitle());
workbook.cloneSheet(workbook.getSheetIndex("Original Sheet 2"), dataMap.get(6).getSheetTitle());
workbook.removeSheetAt(workbook.getSheetIndex("Original Sheet 2")); // Remove the template sheet
workbook.setSheetOrder("Original Sheet 1", 0);
for (ReportPresenter presenter : dataMap.values()) {
String sheetTitle = presenter.getSheetTitle();
int oldIndex = workbook.getSheetIndex(workbook.getSheet(sheetTitle));
workbook.setSheetOrder(sheetTitle, presenter.getAnalysisNumber());
int newIndex = workbook.getSheetIndex(workbook.getSheet(sheetTitle));
System.out.println(oldIndex + " -> " + newIndex);
}
workbook.setSheetOrder("Original Sheet 3", dataMap.size() + 1);
workbook.setSheetOrder("Original Sheet 4", dataMap.size() + 2);
String filePath = "./ExcelNew.xlsx";
try (FileOutputStream fileOut = new FileOutputStream(filePath)) {
workbook.write(fileOut);
}
}
}
static class ReportPresenter {
String sheetTitle = "";
int analysisNumber = -1;
public ReportPresenter(String sheetTitle, int analysisNumber) {
this.sheetTitle = sheetTitle;
this.analysisNumber = analysisNumber;
}
public int getAnalysisNumber() {
return this.analysisNumber;
}
public String getSheetTitle() {
return this.sheetTitle;
}
}
}
在控制台上打印以下內容:
axel@arichter:~/Dokumente/JAVA/poi/poi-4.1.1$ javac -Xlint:deprecation -Xlint:unchecked -cp .:./*:./lib/*:./ooxml-lib/* ExcelSetSheetOrder.java
axel@arichter:~/Dokumente/JAVA/poi/poi-4.1.1$ java -cp .:./*:./lib/*:./ooxml-lib/* ExcelSetSheetOrder
3 -> 1
4 -> 2
5 -> 3
6 -> 4
7 -> 5
8 -> 6
並導致此結果ExcelNew.xlsx
:
事實證明,我對 XSSFWorkbook::setSheetOrder 的工作方式有誤解。
我假設(錯誤地)設置工作表的順序會使工作表保持在那個位置,有點像將工作表插入到數組的索引中。 但是,如果您最近的調用隱式修改了上次調用中使用的工作表前面的順序,則對 setSheetOrder 的后續調用將修改其他工作表的工作表順序。
例如,如果您有這樣訂購的工作表:
[StaticX, StaticY, Cloned3, Cloned4, Cloned1, Cloned2] 然后你調用 setSheetOrder("Cloned3", 3)
訂單變成
[StaticX, StaticY, Cloned4, Cloned3, Cloned1, Cloned2] 這是需要的。
但是,對 setSheetOrder("Cloned1", 1) 的后續調用現在將使訂單
[StaticX, Cloned1, StaticY, Cloned4, Cloned3, Cloned2] 已將 Cloned3 移出位置 3。
在我的調試打印中,我認為它正在工作,因為我只是檢查最后一次調用設置的順序,這當然每次都是正確的,但是當我在每次設置工作表順序后開始打印所有工作表的順序時,問題變得很明顯。
為了解決這個問題,我只是按照我想要的順序將我所有的工作表名稱放入一個數組中,並按順序設置工作表的順序,這很好用。
非常感謝 Axel 提供了這個最小的例子。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.