使用OpenXML和C#,Integers和DateTime导出到Excel

时间:2013-10-15 14:13:03

标签: c# excel datetime openxml

我正在编写一个应该从地图应用程序导出数据的应用程序。 此应用程序正在使用Silverlight,为了便于导出到Excel,我正在使用this库。 默认情况下,所有数据都以字符串表示。当我写入电子表格时,我尝试解析每个字符串以查看它是什么类型:

string str = kvp.Value;
int i = 0;
long l = 0;
decimal dec = 0;
DateTime dt;
if (int.TryParse(str, out i))
    doc.Workbook.Sheets[0].Sheet.Rows[r].Cells[c].SetValue(i);
else if (decimal.TryParse(str, out dec))
    doc.Workbook.Sheets[0].Sheet.Rows[r].Cells[c].SetValue(dec);
else if (long.TryParse(str, out l))
    doc.Workbook.Sheets[0].Sheet.Rows[r].Cells[c].SetValue(l);
else if (DateTime.TryParse(str, out dt))
    doc.Workbook.Sheets[0].Sheet.Rows[r].Cells[c].SetValue(dt);
else
    doc.Workbook.Sheets[0].Sheet.Rows[r].Cells[c].SetValue(str);

除了DateTime以及当我尝试解析一个社会安全号码(在我的情况下是12个字符)时,这很有效。

社会安全号码被解析为十进制数字,并在Excel中以科学形式显示。从我通过阅读收集到的内容看起来似乎是Excel中的限制。但是,如果我标记了单元格,我会在顶部栏中看到正确的数字,您可以在其中编写公式。到目前为止,我已经解决了这个问题,只需将这个数字作为字符串并让最终用户暂时处理它,但我真的希望它成为完成文档中的数字。这可能吗?

真正让我难以置信的是DateTime。日期的格式来自应用程序:2013年10月15日上午1:10:00。 它在Excel文件中看起来像这样:2455075。

我检查了源代码的日期格式,但我似乎不够熟练,看看它是否有任何错误。如果是任何人,请查看here

SetValue函数应该自动识别以下类型:

  • BOOL
  • 日期时间
  • 小数
  • 异常
  • SharedStringDefinition
  • 字符串

我为这篇长篇大论道歉。归结为这些问题:

  • 我可以让Excel以编程方式处理没有科学记数法的长数字吗?
  • 为什么将DateTime输出到如此奇怪的格式?

1 个答案:

答案 0 :(得分:2)

要在日期格式中设置单元格值,您必须将DateTime转换为OLE自动化日期。您还可以创建更清晰的方法来编写单元格值。像这样的事情:

public bool UpdateValue(WorkbookPart wbPart, string sheetName, string addressName, string value,
                            UInt32Value styleIndex, CellValues dataType)
    {
        // Assume failure.
        bool updated = false;

        Sheet sheet = wbPart.Workbook.Descendants<Sheet>().Where(
            (s) => s.Name == sheetName).FirstOrDefault();

        if (sheet != null)
        {
            Worksheet ws = ((WorksheetPart)(wbPart.GetPartById(sheet.Id))).Worksheet;
            Cell cell = InsertCellInWorksheet(ws, addressName);

            if (dataType == CellValues.SharedString)
            {
                // Either retrieve the index of an existing string,
                // or insert the string into the shared string table
                // and get the index of the new item.
                int stringIndex = InsertSharedStringItem(wbPart, value);

                cell.CellValue = new CellValue(stringIndex.ToString());
            }
            else
            {
                cell.CellValue = new CellValue(value);
            }

            cell.DataType = new EnumValue<CellValues>(dataType);

            if (styleIndex > 0)
                cell.StyleIndex = styleIndex;

            // Save the worksheet.
            ws.Save();
            updated = true;
        }

        return updated;
    }

然后像这样调用这个方法(第一个调用是String,第二个调用是DateTime):

UpdateValue(workbookPart, wsName, "D14", "Some text", 0, CellValues.String);

UpdateValue(workbookPart, wsName, "H13", DateTime.Parse("2013-11-01").ToOADate().ToString(CultureInfo.InvariantCulture), 0, CellValues.Date);