【问题标题】:Workbook cell style in POI/NPOI doesn't work properly with multiple styles in workbookPOI/NPOI 中的工作簿单元格样式不适用于工作簿中的多种样式
【发布时间】:2018-03-06 14:06:19
【问题描述】:

我在使用 .Net 版本的 Excel 电子表格 POI 库时遇到了奇怪的问题。我正在从文本文件重写为 Excel 97-2003 文档,并且我想以编程方式添加一些格式,这取决于程序请求时收集的一些值。

一开始,在我从给定值创建一个新单元格的相同方法中,我也在创建一个新的工作簿 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

我的想法已经不多了,也许我应该创建单元格样式的每种组合(我只使用了很少的数据格式和对齐方式)但在我这样做之前(因为我已经没有简单的选项了)现在)我想知道你们认为应该在这里做什么。

cell format is set to custom with date type

【问题讨论】:

    标签: formatting apache-poi excel-2003 npoi


    【解决方案1】:

    我正在使用此代码来创建我的自定义样式和格式。它适用于 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;
      }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-03
      相关资源
      最近更新 更多