【问题标题】:OpenXML SDK: How to identify data type of cell?OpenXML SDK:如何识别单元格的数据类型?
【发布时间】:2016-03-07 08:32:28
【问题描述】:

我正在开发 OPenXML SDK 以使用 excel。目前,我面临一个问题,如何识别单元格、日期时间或数字的数据类型。因为,如果单元格的类型是日期,我们需要再次将双精度值转换为日期时间。

【问题讨论】:

  • This answer 可能会有帮助
  • 感谢您的反馈,但我找到了 Epplus 库。它又快又好

标签: .net excel openxml


【解决方案1】:

根据我从 OpenXML SDK 帮助文件中找到的信息,我编写了以下代码来回答您的问题

public class ExcelEngine : IExcelEngine
{
    private readonly SpreadsheetDocument _wb;
    private WorkbookPart _wbp;
    private SharedStringTablePart _sstp;

    // Used to cache the lookup of worksheet parts
    private Dictionary<string, WorksheetPart> _wsParts = new Dictionary<string, WorksheetPart>();

    #region Constructors

    public ExcelEngine(Stream stream)
    {
        Contracts.IsNotNull(stream);

        _wb = SpreadsheetDocument.Open(stream, false);
        Initialise();
    }

    public ExcelEngine(string fileName)
    {
        Contracts.IsNullOrWhiteSpace(fileName);

        _wb = SpreadsheetDocument.Open(fileName, false);
        Initialise();
    }

    #endregion

    #region IExcelEngine

    /// <summary>
    /// Get the list of sheet names from the spreadsheet
    /// </summary>
    /// <returns></returns>
    public IList<string> GetSheetNames()
    {
        return _wbp.Workbook
            .Descendants<Sheet>()
            .Select(s => s.Name.Value)
            .ToList<String>();
    }

    /// <summary>
    /// Given a sheet name and a cell reference, return the contents of the cell
    /// </summary>
    /// <param name="sheetName"></param>
    /// <param name="addressName"></param>
    /// <returns></returns>        
    public string GetCellValue(string sheetName, string addressName)
    {
        return GetCellValueLocal(sheetName, addressName);
    }


    /// <summary>
    /// Given a sheet name and a cell reference, return the contents of the cell as a boolean value
    /// </summary>
    /// <param name="sheetName"></param>
    /// <param name="addressName"></param>
    /// <returns></returns>
    public bool GetCellBool(string sheetName, string addressName)
    {
        var value = GetCellValueLocal(sheetName, addressName);

        bool result;
        bool.TryParse(value, out result);

        return result;
    }

    #endregion

    #region Private Methods

    private void Initialise()
    {
        _wbp = _wb.WorkbookPart;
        _sstp = _wbp.GetPartsOfType<SharedStringTablePart>().First();
    }


    private string GetCellValueLocal(string sheetName, string addressName)
    {
        string value = null;

        WorksheetPart wsPart = GetWorkSheetPart(sheetName);

        // Use its Worksheet property to get a reference to the cell 
        // whose address matches the address you supplied.
        Cell cell = wsPart.Worksheet.Descendants<Cell>().
            Where(c => c.CellReference == addressName).FirstOrDefault();

        if (cell != null)
        {
            value = cell.InnerText;

            if (cell.DataType != null)
                switch (cell.DataType.Value)
                {
                    case CellValues.SharedString:
                        int ssid = int.Parse(cell.CellValue.Text);
                        value = _sstp.SharedStringTable.ElementAt(ssid).InnerText;
                        break;

                    case CellValues.Boolean:
                        switch (value)
                        {
                            case "0":
                                value = "FALSE";
                                break;
                            default:
                                value = "TRUE";
                                break;
                        }
                        break;

                    case CellValues.Date:
                        break;

                    case CellValues.String:
                        break;
                }
            Debug.WriteLine($"Cell {cell.CellReference}: '{value}'");
        }

        return value;
    }

    private WorksheetPart GetWorkSheetPart(string sheetName)
    {
        // Does it exist in the cache? If not, load it
        if (!_wsParts.ContainsKey(sheetName))
        {
            // Find the sheet with the supplied name, and then use that 
            // Sheet object to retrieve a reference to the first worksheet.
            Sheet theSheet = _wbp.Workbook.Descendants<Sheet>()
                .Where(s => s.Name == sheetName)
                .FirstOrDefault();

            // If not sheet throw an exception
            if (theSheet == null)
                throw new ArgumentException($"Sheet {sheetName} not found in workbook");

            // Retrieve a reference to the worksheet part.
            _wsParts.Add(sheetName, (WorksheetPart) (_wbp.GetPartById(theSheet.Id)));
        }

        return _wsParts[sheetName];
    }

    #endregion

    public void Dispose()
    {
        _wb.Close();
        _wb.Dispose();
    }
}

【讨论】:

  • 日期或日期时间呢?因为这个问题是日期或日期时间特定的。
  • 在作者改进之前,我不得不给出这个答案 -1,因为这会误导许多像我这样的人并花时间碰壁。我发现日期和数字不是 Cell.DataType 的一部分,它将为空。您必须参考另一种方法,如链接所示:stackoverflow.com/questions/36670768/…
  • 它解决了我的问题,感谢我投票,
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-07-21
  • 1970-01-01
  • 1970-01-01
  • 2015-11-07
  • 2016-10-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多