There is a different behavior between shifting rows in .xls and .xlsx files. I have a snippet below which I use to copy rows. In 2.2.3, it was broken for .xlsx but a user told me here that it is fine now: http://stackoverflow.com/questions/41369004/npoi-poi-excel-lib-isheet-shiftrows-index-out-of-range-exception.
Here's my function:
Here's my function:
public void CopyRow(IWorkbook iWorkbook, ISheet iSheet, int sourceRowNum, int destinationRowNum)
{
// Get the source / new row
IRow newRow = iSheet.GetRow(destinationRowNum);
IRow sourceRow = iSheet.GetRow(sourceRowNum);
if (newRow == null)
{
iSheet.CreateRow(destinationRowNum);
newRow = iSheet.GetRow(destinationRowNum);
}
if (newRow.RowNum != destinationRowNum)
{
destinationRowNum = newRow.RowNum;
}
// If the row exist in destination, push down all rows by 1 else create a new row
if (newRow != null)
{
iSheet.ShiftRows(destinationRowNum, iSheet.LastRowNum, 1);
}
else
{
newRow = iSheet.CreateRow(destinationRowNum);
}
//newRow = iSheet.GetRow(destinationRowNum);
// Loop through source columns to add to new row
for (int i = 0; i < sourceRow.LastCellNum; i++)
{
// Grab a copy of the old/new cell
ICell oldCell = sourceRow.GetCell(i);
ICell newCell = newRow.CreateCell(i);
// If the old cell is null jump to next cell
if (oldCell == null)
{
newCell = null;
continue;
}
// Copy style from old cell and apply to new cell
//ICellStyle newCellStyle = iWorkbook.CreateCellStyle();
//newCellStyle.CloneStyleFrom(oldCell.CellStyle);
//;
//newCell.CellStyle = newCellStyle;
newCell.CellStyle = oldCell.CellStyle;
// If there is a cell comment, copy
if (oldCell.CellComment != null)
{
newCell.CellComment = oldCell.CellComment;
}
// If there is a cell hyperlink, copy
if (oldCell.Hyperlink != null)
{
newCell.Hyperlink = oldCell.Hyperlink;
}
// Set the cell data type
newCell.SetCellType(oldCell.CellType);
// Set the cell data value
switch (oldCell.CellType)
{
case CellType.Blank:
newCell.SetCellValue(oldCell.StringCellValue);
break;
case CellType.Boolean:
newCell.SetCellValue(oldCell.BooleanCellValue);
break;
case CellType.Error:
newCell.SetCellErrorValue(oldCell.ErrorCellValue);
break;
case CellType.Formula:
newCell.SetCellFormula(oldCell.CellFormula);
break;
case CellType.Numeric:
newCell.SetCellValue(oldCell.NumericCellValue);
break;
case CellType.String:
newCell.SetCellValue(oldCell.RichStringCellValue);
break;
}
}
// If there are are any merged regions in the source row, copy to new row
for (int i = 0; i < iSheet.NumMergedRegions; i++)
{
CellRangeAddress cellRangeAddress = iSheet.GetMergedRegion(i);
if (cellRangeAddress.FirstRow == sourceRow.RowNum)
{
CellRangeAddress newCellRangeAddress = new CellRangeAddress(newRow.RowNum,
(newRow.RowNum +
(cellRangeAddress.LastRow - cellRangeAddress.FirstRow
)),
cellRangeAddress.FirstColumn,
cellRangeAddress.LastColumn);
iSheet.AddMergedRegion(newCellRangeAddress);
}
}
}
If you step through it using an .xls file, it works as it did in NPOI 2.2.3. However, using an .xlsx file, the newRow.RowNum increases + 1 from the original destinationRowNum it was set to after calling ShiftRows, while with an .xls the newRow.RowNum stays the same. This ends up with null reference exceptions. Anyone have a workaround or know why they behave differently?