标签:
利用NPOI进行Excel的工作表(Sheet)复制时,如果复制的工作表(Sheet)较多(100个左右),会报告 workbook 的 cellstyle 创建不能超过4000 的错误.
代码如下:
public static void CopySheet(ISheet fromSheet, ISheet toSheet, bool copyValueFlag)
{
//合并区域处理
MergerRegion(fromSheet, toSheet);
System.Collections.IEnumerator rows = fromSheet.GetRowEnumerator();
while (rows.MoveNext())
{
IRow row = null;
if (fromSheet.Workbook is HSSFWorkbook)
row = rows.Current as HSSFRow;
else
row = rows.Current as HSSFRow;
IRow newRow = toSheet.CreateRow(row.RowNum);
CopyRow(fromSheet.Workbook, toSheet.Workbook, row, newRow, copyValueFlag);
}
}
public static void CopyRow(IWorkbook fromWb, IWorkbook toWb, IRow fromRow, IRow toRow, bool copyValueFlag)
{
System.Collections.IEnumerator cells = fromRow.GetEnumerator(); //.GetRowEnumerator();
toRow.Height = fromRow.Height;
while (cells.MoveNext())
{
ICell cell = null;
//ICell cell = (wb is HSSFWorkbook) ? cells.Current as HSSFCell : cells.Current as NPOI.XSSF.UserModel.XSSFCell;
if (toWb is HSSFWorkbook)
cell = cells.Current as HSSFCell;
else
cell = cells.Current as HSSFCell;
ICell newCell = toRow.CreateCell(cell.ColumnIndex);
CopyCell(fromWb, toWb, cell, newCell, copyValueFlag);
}
}
public static void CopyCell(IWorkbook fromWb,IWorkbook toWb, ICell srcCell, ICell distCell, bool copyValueFlag)
{
ICellStyle newstyle = toWb.CreateCellStyle(); //复制样式
newstyle.CloneStyleFrom(srcCell.CellStyle);
//样式
distCell.CellStyle = newstyle;
//评论
if (srcCell.CellComment != null)
{
distCell.CellComment = srcCell.CellComment;
}
// 不同数据类型处理
CellType srcCellType = srcCell.CellType;
distCell.SetCellType(srcCellType);
if (copyValueFlag)
{
if (srcCellType == CellType.Numeric)
{
if (HSSFDateUtil.IsCellDateFormatted(srcCell))
{
distCell.SetCellValue(srcCell.DateCellValue);
}
else
{
distCell.SetCellValue(srcCell.NumericCellValue);
}
}
else if (srcCellType == CellType.String)
{
distCell.SetCellValue(srcCell.RichStringCellValue);
}
else if (srcCellType == CellType.Blank)
{
// nothing21
}
else if (srcCellType == CellType.Boolean)
{
distCell.SetCellValue(srcCell.BooleanCellValue);
}
else if (srcCellType == CellType.Error)
{
distCell.SetCellErrorValue(srcCell.ErrorCellValue);
}
else if (srcCellType == CellType.Formula)
{
distCell.SetCellFormula(srcCell.CellFormula);
}
else
{
// nothing29
}
}
}
网上有方法说要把CreateCellStyle放在循环外面,这个方法不适用于复制的工作表(Sheet)较多(100个左右)的场景,且不是解决问题的根本方法.
为了最大限度的复用CellStyle,且控制在4000个之内.构造了一个缓存对象.来缓存创建的CellStyle,所有的CellStyle获取,先通过从缓存取,如果不存在再创建.代码如下:
public class CellStyleCache:ArrayList
{
public ICellStyle this[ICellStyle fromStyle]
{
get
{
foreach (object o in this)
{
ICellStyle toStyle = o as ICellStyle;
if
(
toStyle.Alignment == fromStyle.Alignment
//边框和边框颜色
&& toStyle.BorderBottom == fromStyle.BorderBottom
&& toStyle.BorderLeft == fromStyle.BorderLeft
&& toStyle.BorderRight == fromStyle.BorderRight
&& toStyle.BorderTop == fromStyle.BorderTop
&& toStyle.TopBorderColor == fromStyle.TopBorderColor
&& toStyle.BottomBorderColor == fromStyle.BottomBorderColor
&& toStyle.RightBorderColor == fromStyle.RightBorderColor
&& toStyle.LeftBorderColor == fromStyle.LeftBorderColor
//背景和前景
&& toStyle.FillBackgroundColor == fromStyle.FillBackgroundColor
&& toStyle.FillForegroundColor == fromStyle.FillForegroundColor
//&& toStyle.DataFormat == fromStyle.DataFormat
//&& toStyle.FillPattern == fromStyle.FillPattern
&& toStyle.IsHidden == fromStyle.IsHidden
//&& toStyle.Indention == fromStyle.Indention//首行缩进
//&& toStyle.IsLocked == fromStyle.IsLocked
//&& toStyle.Rotation == fromStyle.Rotation//旋转
&& toStyle.VerticalAlignment == fromStyle.VerticalAlignment
//&& toStyle.WrapText == fromStyle.WrapText
)
{
return toStyle;
}
}
return null;
}
set
{
this.Add(fromStyle);
}
}
} public static void CopyCell(IWorkbook fromWb,IWorkbook toWb, ICell srcCell, ICell distCell, bool copyValueFlag)
{
//ICellStyle newstyle = toWb.CreateCellStyle();
ICellStyle newstyle = CreateCellStyle(toWb, srcCell.CellStyle); //复制样式
newstyle.CloneStyleFrom(srcCell.CellStyle);
//样式
distCell.CellStyle = newstyle;
//评论
if (srcCell.CellComment != null)
{
distCell.CellComment = srcCell.CellComment;
}
// 不同数据类型处理
CellType srcCellType = srcCell.CellType;
distCell.SetCellType(srcCellType);
if (copyValueFlag)
{
if (srcCellType == CellType.Numeric)
{
if (HSSFDateUtil.IsCellDateFormatted(srcCell))
{
distCell.SetCellValue(srcCell.DateCellValue);
}
else
{
distCell.SetCellValue(srcCell.NumericCellValue);
}
}
else if (srcCellType == CellType.String)
{
distCell.SetCellValue(srcCell.RichStringCellValue);
}
else if (srcCellType == CellType.Blank)
{
// nothing21
}
else if (srcCellType == CellType.Boolean)
{
distCell.SetCellValue(srcCell.BooleanCellValue);
}
else if (srcCellType == CellType.Error)
{
distCell.SetCellErrorValue(srcCell.ErrorCellValue);
}
else if (srcCellType == CellType.Formula)
{
distCell.SetCellFormula(srcCell.CellFormula);
}
else
{
// nothing29
}
}
}
private static CellStyleCache styleCache = new CellStyleCache();
public static ICellStyle CreateCellStyle(IWorkbook wb,ICellStyle fromStyle)
{
ICellStyle newStyle = styleCache[fromStyle];
if (newStyle == null)
{
newStyle = wb.CreateCellStyle();
}
return newStyle;
}
测试通过.
npoi workbook 的 cellstyle 创建不能超过4000的解决方法
标签:
原文地址:http://blog.csdn.net/sharpnessdotnet/article/details/43407465