[英]Apache POI Error 'unreadable content' When Using addMergedRegion
I am getting the below Excel error when I use addMergedRegion
.使用addMergedRegion
时出现以下 Excel 错误。 This is my code:这是我的代码:
spreadsheet.addMergedRegion(new CellRangeAddress(a+1, b, 1, 1));
The error I get in Excel says that the downloaded file has "unreadable content" and asks if I want to recover the contents.我在 Excel 中得到的错误说下载的文件有“不可读的内容”,并询问我是否要恢复内容。 I click yes.我点击是。
Excel then opens the file and a window says that it repaired or removed what was wrong and then it says: Excel 然后打开文件,window 说它修复或删除了错误的内容,然后说:
I check those sheets for the cell I wanted merged, and it's merged exactly the way I want it.我检查那些工作表中我想要合并的单元格,它完全按照我想要的方式合并。
So why is Excel giving me this error, and how do I fix it?那么为什么 Excel 给我这个错误,我该如何解决呢? Thanks.谢谢。
Edit 1: Added additional code.编辑 1:添加了附加代码。 I have a sheet like this and I want to merge the rows with same value.我有一张这样的工作表,我想合并具有相同值的行。 Input输入
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));
Your programming logic is wrong and produces overlapping merged regions.您的编程逻辑是错误的,会产生重叠的合并区域。 That is what Excel does not tolerate and alerts the error about.这是 Excel 不能容忍并警告错误的原因。
You program does the following: It starts with int b=i; int a=i;
您的程序执行以下操作:它以int b=i; int a=i;
int b=i; int a=i;
where i
points to the first row. i
指向第一行的地方。 The values in first row and second row are equal.第一行和第二行的值相等。 So your program sets a = b;
所以你的程序设置a = b;
so that now both a
and b
point to the first row.所以现在a
和b
都指向第一行。 Then it merges spreadsheet.addMergedRegion(new CellRangeAddress(a+1, b, 1, 1));
然后合并spreadsheet.addMergedRegion(new CellRangeAddress(a+1, b, 1, 1));
. . So it creates <mergeCell ref="B2:B1"/>
.所以它创建了<mergeCell ref="B2:B1"/>
。 This is not really correct as it should be <mergeCell ref="B1:B2"/>
.这并不正确,因为它应该是<mergeCell ref="B1:B2"/>
。 But that Excel would tolerate.但是 Excel 会容忍。 Now i
increases and points to second row.现在i
增加并指向第二行。 The values in second row and third row are not equal.第二行和第三行的值不相等。 So your program sets b = i;
所以你的程序设置b = i;
. . Now b
points to second row but a
has not changed and points to first row.现在b
指向第二行,但a
没有改变并指向第一行。 Now your code merges a+1
and b
which both points to second row.现在您的代码合并a+1
和b
,它们都指向第二行。 So it creates <mergeCell ref="B2:B2"/>
.所以它创建了<mergeCell ref="B2:B2"/>
。 That one-cell-merged-region is useless but would be tolerated by Excel. But it additionally overlaps the former created <mergeCell ref="B2:B1"/>
. one-cell-merged-region 是无用的,但 Excel 可以容忍。但它还与前者创建的<mergeCell ref="B2:B1"/>
重叠。 And here Excel's tolerance ends. Excel 的容忍到此结束。
The following Minimal, Reproducible Example shows a working program logic.以下最小、可重现的示例显示了一个有效的程序逻辑。 It additional shows what Minimal, Reproducible Example really means.它还显示了 Minimal, Reproducible Example 的真正含义。
Have a Excel workbook ExcelExample.xlsx
containing following in columns A
and B
of first sheet:有一个 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
Then do running the following code:然后执行以下代码:
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);
}
}
}
After that it should have produced following result in ExcelExampleNew.xlsx
:之后它应该在ExcelExampleNew.xlsx
中产生以下结果:
Disclaimer: This code is tested and runs using current apache poi 5.2.3
.免责声明:此代码使用当前apache poi 5.2.3
进行测试和运行。 Older apache poi
versions are outdated and not supported anymore.较旧apache poi
版本已过时且不再受支持。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.