简体   繁体   English

Apache 使用 addMergedRegion 时 POI 错误“无法读取的内容”

[英]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输入在此处输入图像描述

Output Output 在此处输入图像描述

        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.所以现在ab都指向第一行。 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+1b ,它们都指向第二行。 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM