Apache POI shiftRows повреждает файл и удаляет содержимое - PullRequest
0 голосов
/ 04 мая 2019

Я хочу заполнить таблицу шаблоном Excel. Я хочу вставить строки и заполнить их. Я использовал библиотеку Java Apache POI для доступа к файлам Excel. Сначала я создал новый файл и заполнил столбец A от строки 1 до 10 номерами 1..10 и сохранил файл. Затем я прочитал файл и попытался вставить одну пустую строку методом 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();

1 Ответ

3 голосов
/ 04 мая 2019

Ваш shiftRows пытается переместить строки между строкой 5 (индекс 4) и строкой 6 (индекс 5) на одну строку вниз.Но как насчет строк 7, 8, 9 и 10?Вам нужно сместить строки между строкой 5 и последней строкой на одну строку вниз, если необходимо получить новую пустую строку 5.

Используя apache poi версию 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);
  } 
 }
}

Но * версии 1009 * больше 3.17, также 4.1.0, имеют ошибку в shiftRows с использованием XSSF.Там после смещения ссылки в ячейках остаются старыми, вместо того, чтобы быть приспособленными к новым строкам.Например, ссылки 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);
  } 
 }
}
...