Apache POI: почему отсутствует строка, когда я использую shiftRows? - PullRequest
2 голосов
/ 18 апреля 2019

Я сдвигаю строки в листе Excel и вставляю новую строку в начало листа.Однако, независимо от того, сколько строк я сдвигаю и вставляю, мне кажется, что в итоге получается на одну строку меньше, чем я должен быть.

import org.apache.poi.ss.usermodel.Row
import   Row.MissingCellPolicy._
import org.apache.poi.ss.usermodel.Sheet
import org.apache.poi.ss.usermodel.Workbook
import org.apache.poi.ss.util.CellRangeAddress
import org.apache.poi.ss.util.WorkbookUtil.createSafeSheetName
import org.apache.poi.xssf.usermodel.XSSFWorkbook

def shiftAndInsertRow(sheet: Sheet) = {

  val rowInsertionPoint = 0

  // shift all the rows down
  val lastRowNum = sheet.getLastRowNum
  println(s"Last row is $lastRowNum")

  val debugRow1 = sheet.getRow(rowInsertionPoint)
  val debugCell1 = debugRow1.getCell(0)
  // let's get a play-by-play of what's being attempted
  println(s"Current value in row $rowInsertionPoint is " +
      s"${debugCell1.getNumericCellValue}")
  println(s"Shifting rows $rowInsertionPoint and below down one row")
  sheet.shiftRows(rowInsertionPoint, lastRowNum, 1, true, true)
  val debugRow2 = sheet.getRow(rowInsertionPoint + 1)
  val debugCell2 = debugRow2.getCell(0)
  println(s"Current value in row ${rowInsertionPoint + 1} is now " +
      s"${debugCell2.getNumericCellValue}")

  println(s"Creating new row at $rowInsertionPoint in sheet")
  // create the new row
  val newRow = sheet.createRow(rowInsertionPoint)
  // set the field ID of the row
  val newCell = newRow.getCell(0, CREATE_NULL_AS_BLANK)
  println(s"Inserting value $lastRowNum at $rowInsertionPoint in sheet")
  newCell.setCellValue(lastRowNum)
  println()

}

val workbook = new XSSFWorkbook()
val sheet = workbook.createSheet(createSafeSheetName("Test 1"))
val rowNum = 0
val cellValue = -1

println(s"Creating new row at $rowNum in sheet")
// create the new row
val row = sheet.createRow(rowNum)
// set the field ID of the row
val cell = row.getCell(0, CREATE_NULL_AS_BLANK)
println(s"Inserting value $cellValue at $rowNum in sheet")
cell.setCellValue(cellValue)
println()
// insert a second row
shiftAndInsertRow(sheet)
// and a third
shiftAndInsertRow(sheet)
workbook.write(new java.io.FileOutputStream("out/test.xlsx"))

Приведенный выше код создает электронную таблицу, содержащую только две строки вместо трех.Чего мне не хватает?

1 Ответ

2 голосов
/ 19 апреля 2019

Я думаю, что ваш код в порядке, мне кажется, что это ошибка в apache-poi.Он работает для меня в версии 3.17, но не работает, если я обновляюсь до 4.0.0.

Насколько я могу судить, номер строки обновляется правильно, но ссылка (cell.getReference) - нет.

Я бы посоветовал попытаться выяснить, была ли здесь уже сообщена ошибка https://bz.apache.org/bugzilla/buglist.cgi?product=POI, а если нет, подать новый отчет об ошибке.

Тем временем, возможно, вы могли бы попробовать этообходной путь, который, кажется, делает трюк для меня.Он вызывает updateCellReferencesForShifting в каждой ячейке таблицы.

import scala.collection.JavaConverters._
for {
  row <- sheet.rowIterator().asScala.toList
  cell <- row.cellIterator().asScala.toList
} yield cell.asInstanceOf[XSSFCell].updateCellReferencesForShifting("")

Поместите этот блок кода сразу после вашего звонка на shiftRows.Нет никаких гарантий, что это не сломает что-то еще, так что используйте с осторожностью!

...