[英]Apache POI Error 'unreadable content' When Using addMergedRegion
使用addMergedRegion
時出現以下 Excel 錯誤。 這是我的代碼:
spreadsheet.addMergedRegion(new CellRangeAddress(a+1, b, 1, 1));
我在 Excel 中得到的錯誤說下載的文件有“不可讀的內容”,並詢問我是否要恢復內容。 我點擊是。
Excel 然后打開文件,window 說它修復或刪除了錯誤的內容,然后說:
我檢查那些工作表中我想要合並的單元格,它完全按照我想要的方式合並。
那么為什么 Excel 給我這個錯誤,我該如何解決呢? 謝謝。
編輯 1:添加了附加代碼。 我有一張這樣的工作表,我想合並具有相同值的行。 輸入
int i=primrowCountSplice; int b=i; int a=i;
for (i=primrowCountSplice;i<primrowCount-1;i++) {
if(spreadsheet.getRow(i).getCell(1).getStringCellValue().equals(spreadsheet.getRow(i+1).getCell(1).getStringCellValue()))
{
out.println("i: " + i);
out.println(spreadsheet.getRow(i).getCell(1).getStringCellValue());
out.println(spreadsheet.getRow(i+1).getCell(1).getStringCellValue());
a = b;
out.println("a: " + a);
} else {
b = i;
out.println("b: " + b);
}
spreadsheet.addMergedRegion(new CellRangeAddress(a+1, b, 1, 1));
您的編程邏輯是錯誤的,會產生重疊的合並區域。 這是 Excel 不能容忍並警告錯誤的原因。
您的程序執行以下操作:它以int b=i; int a=i;
int b=i; int a=i;
i
指向第一行的地方。 第一行和第二行的值相等。 所以你的程序設置a = b;
所以現在a
和b
都指向第一行。 然后合並spreadsheet.addMergedRegion(new CellRangeAddress(a+1, b, 1, 1));
. 所以它創建了<mergeCell ref="B2:B1"/>
。 這並不正確,因為它應該是<mergeCell ref="B1:B2"/>
。 但是 Excel 會容忍。 現在i
增加並指向第二行。 第二行和第三行的值不相等。 所以你的程序設置b = i;
. 現在b
指向第二行,但a
沒有改變並指向第一行。 現在您的代碼合並a+1
和b
,它們都指向第二行。 所以它創建了<mergeCell ref="B2:B2"/>
。 one-cell-merged-region 是無用的,但 Excel 可以容忍。但它還與前者創建的<mergeCell ref="B2:B1"/>
重疊。 Excel 的容忍到此結束。
以下最小、可重現的示例顯示了一個有效的程序邏輯。 它還顯示了 Minimal, Reproducible Example 的真正含義。
有一個 Excel 工作簿ExcelExample.xlsx
在第一張工作表A
列和B
列中包含以下內容:
Col1 Col2
Record1 Value1
Record2 Value1
Record3 Value2
Record4 Value3
Record5 Value3
Record6 Value3
Record7 Value4
Record8 Value5
Record9 Value5
Record10 Value5
Record11 Value6
Record12 Value7
Record13 Value7
Record14 Value7
Record15 Value8
Record16 Value9
Record17 Value10
Record18 Value10
Record19 Value10
Record20 Value10
然后執行以下代碼:
import java.io.FileInputStream;
import java.io.FileOutputStream;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
public class ExcelMergeRowsByContent {
static void mergeRowsByContent(Sheet sheet, int col) {
int firstRow = sheet.getFirstRowNum();
int lastRow = sheet.getLastRowNum();
DataFormatter dataFormatter = new DataFormatter();
dataFormatter.setUseCachedValuesForFormulaCells(true);
int fromRow = firstRow;
int toRow = 0;
boolean merge = false;
while(fromRow <= lastRow) {
Row row1 = sheet.getRow(fromRow); if (row1 == null) row1 = sheet.createRow(fromRow);
Cell cell1 = row1.getCell(col);
String cellValue1 = dataFormatter.formatCellValue(cell1);
toRow = fromRow + 1;
while (toRow <= lastRow) { // check whether following values are equal
Row row2 = sheet.getRow(toRow); if (row2 == null) row2 = sheet.createRow(toRow);
Cell cell2 = row2.getCell(col);
String cellValue2 = dataFormatter.formatCellValue(cell2);
System.out.println("cell value in row " + fromRow + " = " + cellValue1 + "; cell value in row " + toRow + " = " + cellValue2);
if (cellValue2.equals(cellValue1)) {
merge = true; // merging is needed
toRow++; // try whether next row also has equal value
} else {
break; // values were not equal, so break searching
}
}
if (merge) {
toRow--; // merge only rows where values are equal, last toRow was not
System.out.println("merging from row " + fromRow + " to row " + toRow);
sheet.addMergedRegion(new CellRangeAddress(fromRow, toRow, col, col));
fromRow = toRow;
}
merge = false;
fromRow++;
}
}
public static void main(String[] args) throws Exception {
try (
FileInputStream in = new FileInputStream("./ExcelExample.xlsx"); FileOutputStream out = new FileOutputStream("./ExcelExampleNew.xlsx");
//FileInputStream in = new FileInputStream("./ExcelExample.xls"); FileOutputStream out = new FileOutputStream("./ExcelExampleNew.xls");
Workbook workbook = WorkbookFactory.create(in); ) {
Sheet sheet = workbook.getSheetAt(0);
mergeRowsByContent(sheet, 1);
workbook.write(out);
}
}
}
之后它應該在ExcelExampleNew.xlsx
中產生以下結果:
免責聲明:此代碼使用當前apache poi 5.2.3
進行測試和運行。 較舊apache poi
版本已過時且不再受支持。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.