我遇到了Excel电子表格的.Net版POI库的奇怪问题。我从文本文件重写为Excel 97-2003文档,我想以编程方式添加一些格式,取决于在程序的乞讨时收集的一些值。
一开始,在我从给定值创建新单元格的同一方法中,我创建了一个新的Workbook CellStyle,这是错误的,因为我很快就用完了样式(或者我只是想到它是问题的原因)。
负责Excel工作簿的类的构造函数:
public OldExcelWriter(TextWriter logger) : base(logger)
{
_workbook = new HSSFWorkbook();
_sheetData = _workbook.CreateSheet("sheet1");
_creationHelper = _workbook.GetCreationHelper();
}
调用所有操作链的方法:
public void Write(string path, Data data)
{
FillSpreadSheetWithData(data, _sheetData);
SaveSpreadSheet(_workbook, path);
}
长话短说,在FillSpreadSheetWithData中我有一个创建行的方法,其中我为每个单元格都有一个循环,所以基本上我通过每列重复迭代,将IRow引用传递给一行,列像这样的价值,索引和格式信息:
for (int j = 0; j < column.Count; j++)
{
CreateCell(row, column[j], j, data.Formatting[j]);
}
并且在创建新样式时(对于第一次拍摄,我试图传递一些日期时间值)我在重写的Excel中有这样的情况:screenshot of excel workbook
因此格式化正确传递(也是水平对齐等),但在第15行(总是相同的数量)后变得难看。
DateTime dataCell = DateTime.MaxValue;
var cell = row.CreateCell(columnIndex);
_cellStyle = _workbook.CreateCellStyle();
switch (format.Type)
{
case DataType.Date:
_cellStyle.DataFormat = _creationHelper.CreateDataFormat().GetFormat("m/dd/yyyy");
if (value.Replace("\n", "") != string.Empty)
{
dataCell = DateTime.ParseExact(value.Replace("\n", ""), "m/dd/yyyy",
System.Globalization.CultureInfo.InvariantCulture);
}
break;
}
switch (format.HorizontalAlignment)
{
case Enums.HorizontalAlignment.Left:
_cellStyle.Alignment = HorizontalAlignment.LEFT;
break;
case Enums.HorizontalAlignment.Center:
_cellStyle.Alignment = HorizontalAlignment.CENTER;
break;
}
if (dataCell != DateTime.MaxValue)
{
cell.CellStyle = _cellStyle;
cell.SetCellValue(dataCell);
dataCell = DateTime.MaxValue;
}
else
{
cell.CellStyle = _cellStyle;
cell.SetCellValue(value);
}
(这不是最干净的代码,但在完成这项工作后我不会重构。)
遇到这个问题之后,我想也许我会在构造函数中创建_cellStyle变量,并且只改变它的值取决于具体情况,因为它无论如何都被分配给新单元格而且我看到了调试对象值是否正确。
但是在创造了一切之后,它不会变得更好。样式的最后一个值覆盖样式,日期也被破坏,但稍后:screnshoot of excel workbook after creating one instance of cell style
我没有想法,也许我应该创建单元格样式的每种组合(我只使用少量数据格式和对齐)但在此之前我会这样做(因为我&#39; m现在用完了简单的选项)我想知道你们认为应该在这里做些什么。
答案 0 :(得分:0)
我正在使用此代码创建自定义样式和格式。它用于excel表的XSSF格式。但它会对HSSF格式有所改进。
XSSFFont defaultFont = (XSSFFont)workbook.CreateFont();
defaultFont.FontHeightInPoints = (short)10;
defaultFont.FontName = "Arial";
defaultFont.Color = IndexedColors.Black.Index;
defaultFont.IsBold = false;
defaultFont.IsItalic = false;
XSSFCellStyle dateCellStyle = (XSSFCellStyle)workbook.CreateCellStyle();
XSSFDataFormat dateDataFormat = (XSSFDataFormat)workbook.CreateDataFormat();
dateCellStyle.SetDataFormat(dateDataFormat.GetFormat("m/d/yy h:mm")); //Replace format by m/dd/yyyy. try similar approach for phone number etc.
dateCellStyle.FillBackgroundColor = IndexedColors.LightYellow.Index;
//dateCellStyle.FillPattern = FillPattern.NoFill;
dateCellStyle.FillForegroundColor = IndexedColors.LightTurquoise.Index;
dateCellStyle.FillPattern = FillPattern.SolidForeground;
dateCellStyle.Alignment = HorizontalAlignment.Left;
dateCellStyle.VerticalAlignment = VerticalAlignment.Top;
dateCellStyle.BorderBottom = BorderStyle.Thin;
dateCellStyle.BorderTop = BorderStyle.Thin;
dateCellStyle.BorderLeft = BorderStyle.Thin;
dateCellStyle.BorderRight = BorderStyle.Thin;
dateCellStyle.SetFont(defaultFont);
//Apply your style to column
_sheetData.SetDefaultColumnStyle(columnIndex, dateCellStyle);
// Or you can also apply style cell wise like
var row = _sheetData.CreateRow(0);
for (int cellIndex = 0;cellIndex < TotalHeaderCount;cellIndex++)
{
row.Cells[cellIndex].CellStyle = dateCellStyle;
}