Java ApachePOI shiftRows会损坏文件并删除内容
我想在表格中填充一个模板excel文件。我想插入行并填充它们。我使用JavaApachePOI库访问excel文件。首先,我创建了一个新文件,用1..10个数字填充了从第1行到第10行的a列,并保存了该文件。然后我读取文件,并尝试使用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");
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行和最后一行之间的行向下移动一行
使用ApachePOIversion3.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
的用户。“…计算未完成。”:这是另一个问题。看见最简单的解决方案:Doworkbook.SetForceFormulaReculation(true)代码>在工作簿之前。写(出)代码>。太好了,非常感谢。如何创建与指定行的(边框、样式等)相同的新行?我想有一个表格模板和填充行,所以需要保持风格。我可以克隆一行并将其填充为一行,插入数据行并保留最后一行的总和。@Moh Tarvirdi:提出具体问题并得到具体答案,这就是Stackoverflow的工作原理。在评论中一个接一个地问后续问题并不是Stackoverflow的工作原理。请就另一个问题提出新问题,并在新问题中提供所有必要的信息。Stackoverflow问题/答案也将对其他读者有所帮助,而不仅仅是对你。Stackoverflow不是一个支持论坛。亲爱的Axel,是的,你是对的。我会做你的推荐。再次感谢你的建议。