Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java ApachePOI shiftRows会损坏文件并删除内容_Java_Apache Poi - Fatal编程技术网

Java ApachePOI shiftRows会损坏文件并删除内容

Java ApachePOI shiftRows会损坏文件并删除内容,java,apache-poi,Java,Apache Poi,我想在表格中填充一个模板excel文件。我想插入行并填充它们。我使用JavaApachePOI库访问excel文件。首先,我创建了一个新文件,用1..10个数字填充了从第1行到第10行的a列,并保存了该文件。然后我读取文件,并尝试使用sheet.shiftRows()方法插入一个空行。我尝试了下面的代码,但输出文件在打开(读取)时出现问题,第5、6、7行为空,未发生移动 InputStream inputStream = new FileInputStream("TestIn-1.xlsx");

我想在表格中填充一个模板excel文件。我想插入行并填充它们。我使用JavaApachePOI库访问excel文件。首先,我创建了一个新文件,用1..10个数字填充了从第1行到第10行的a列,并保存了该文件。然后我读取文件,并尝试使用
sheet.shiftRows()
方法插入一个空行。我尝试了下面的代码,但输出文件在打开(读取)时出现问题,第5、6、7行为空,未发生移动

InputStream inputStream = new FileInputStream("TestIn-1.xlsx");
Workbook workbookIn = new XSSFWorkbook(inputStream);
Sheet sheetIn = workbookIn.getSheet("Sheet1");

sheetIn.shiftRows(4,5,1);

OutputStream outputStream = new FileOutputStream("TestOut.xlsx");
workbookIn.write(outputStream);
outputStream.close();

您的
shiftRows
尝试将第5行(索引4)和第6行(索引5)之间的行向下移动一行。但是第7、8、9和10排呢?如果需要获得新的空第5行,则需要将第5行和最后一行之间的行向下移动一行

使用ApachePOI
version
3.17
这非常简单:

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.*;

import java.io.FileInputStream;
import java.io.FileOutputStream;

class ExcelReadShiftRowsAndWrite {

 public static void main(String[] args) throws Exception {
  //String fileIn= "TestIn.xls";
  //String fileOut= "TestOut.xls";
  String fileIn= "TestIn.xlsx";
  String fileOut= "TestOut.xlsx";

  try (Workbook workbook = WorkbookFactory.create(new FileInputStream(fileIn));
       FileOutputStream out = new FileOutputStream(fileOut)) {

   Sheet sheet = workbook.getSheet("Sheet1");

   sheet.shiftRows(4, sheet.getLastRowNum(), 1); //shifts rows between row 5 (index 4) and last row one row down

   workbook.write(out);
  } 
 }
}
但是
apachepoi
版本大于
3.17
,也大于
4.1.0
,使用
XSSF
shiftRows
中有一个bug。在那里,移动后,单元格中的引用保持为旧的,而不是调整为新行。例如,参考文献
A5
A6
。。。向下换档后保持不变,而不是调整到
A6
A7

因此,必须纠正此错误:

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.*;

import java.io.FileInputStream;
import java.io.FileOutputStream;

class ExcelReadShiftRowsAndWrite {

 public static void main(String[] args) throws Exception {
  //String fileIn= "TestIn.xls";
  //String fileOut= "TestOut.xls";
  String fileIn= "TestIn.xlsx";
  String fileOut= "TestOut.xlsx";

  try (Workbook workbook = WorkbookFactory.create(new FileInputStream(fileIn));
       FileOutputStream out = new FileOutputStream(fileOut)) {

   Sheet sheet = workbook.getSheet("Sheet1");

   sheet.shiftRows(4, sheet.getLastRowNum(), 1); //shifts rows between row 5 (index 4) and last row one row down

   if (sheet instanceof XSSFSheet) {  
    XSSFSheet xSSFSheet = (XSSFSheet)sheet;
    // correcting bug that shiftRows does not adjusting references of the cells
    // if row 3 is shifted down, then reference in the cells remain r="A3", r="B3", ...
    // they must be adjusted to the new row thoug: r="A4", r="B4", ...
    // apache poi 3.17 has done this properly but had have other bugs in shiftRows.
    for (int r = xSSFSheet.getFirstRowNum(); r < sheet.getLastRowNum() + 1; r++) {
     XSSFRow row = xSSFSheet.getRow(r); 
     if (row != null) {
      long rRef = row.getCTRow().getR();
      for (Cell cell : row) {
       String cRef = ((XSSFCell)cell).getCTCell().getR();
       ((XSSFCell)cell).getCTCell().setR(cRef.replaceAll("[0-9]", "") + rRef);
      }
     }
    }
    // end correcting bug
   }

   workbook.write(out);
  } 
 }
}
import org.apache.poi.ss.usermodel.*;
导入org.apache.poi.xssf.usermodel.*;
导入java.io.FileInputStream;
导入java.io.FileOutputStream;
类ExcelReadShiftRowsAndWrite{
公共静态void main(字符串[]args)引发异常{
//字符串fileIn=“TestIn.xls”;
//String fileOut=“TestOut.xls”;
字符串fileIn=“TestIn.xlsx”;
String fileOut=“TestOut.xlsx”;
尝试(工作簿=WorkbookFactory.create(新文件输入流(fileIn));
FileOutputStream out=新的FileOutputStream(fileOut)){
Sheet Sheet=工作簿.getSheet(“Sheet1”);
sheet.shiftRows(4,sheet.getLastRowNum(),1);//将第5行(索引4)和最后一行之间的行向下移动一行
if(XSSFSheet的工作表实例){
XSSFSheet XSSFSheet=(XSSFSheet)张;
//修正shiftRows不调整单元格引用的错误
//如果第3行下移,则单元格中的引用保持r=“A3”,r=“B3”。。。
//必须将它们调整到新的行中:r=“A4”,r=“B4”。。。
//ApachePOI3.17已经正确地做到了这一点,但在shiftRows中还有其他缺陷。
对于(int r=xSSFSheet.getFirstRowNum();r
您使用的apache poi版本是什么?特别是
shiftRows
有许多不同的问题,这取决于使用的apache poi`版本。我在开发中使用了poi v4.1。谢谢,更正循环解决了这个问题。我们可以用不依赖于XSSF类型的通用格式编写吗?另一个问题是,修改插入的空行的值时,计算未完成。(将总和添加到行的末尾,并用100填充空白值)@Moh Tarvirdi:“我们可以用不依赖于XSSF类型的通用格式编写吗?”:我的代码与类型无关,除了需要
XSSF
的错误更正之外。“这个错误什么时候解决(估计)?”:我不知道。我不是
apachepoi
开发团队的一员。我只是
apachepoi
的用户。“…计算未完成。”:这是另一个问题。看见最简单的解决方案:Do
workbook.SetForceFormulaReculation(true)
工作簿之前。写(出)。太好了,非常感谢。如何创建与指定行的(边框、样式等)相同的新行?我想有一个表格模板和填充行,所以需要保持风格。我可以克隆一行并将其填充为一行,插入数据行并保留最后一行的总和。@Moh Tarvirdi:提出具体问题并得到具体答案,这就是Stackoverflow的工作原理。在评论中一个接一个地问后续问题并不是Stackoverflow的工作原理。请就另一个问题提出新问题,并在新问题中提供所有必要的信息。Stackoverflow问题/答案也将对其他读者有所帮助,而不仅仅是对你。Stackoverflow不是一个支持论坛。亲爱的Axel,是的,你是对的。我会做你的推荐。再次感谢你的建议。