繁体   English   中英

为什么在将数据导出到 Excel 时日期格式会发生变化?

[英]Why Date format gets change while exporting data to Excel?

我正在处理窗口表单应用程序。 在我的表单中,我有 GridView,其中有一列类型为日期。 日期列的日期格式为 dd-MM-YYYY。我正在将此数据导出到 Excel 中。 但问题是 Excel 中的日期格式发生了变化。

这是我将数据导出到 Excel 时的代码

    private void btnSaveDetails_Click(object sender, EventArgs e)
    {

        Microsoft.Office.Interop.Excel._Application app = new Microsoft.Office.Interop.Excel.Application();
        Microsoft.Office.Interop.Excel._Workbook workbook = app.Workbooks.Add(Type.Missing);
        Microsoft.Office.Interop.Excel._Worksheet worksheet = null;
        app.Visible = true;
        worksheet = workbook.ActiveSheet;
        for (int i = 1; i < dataGridViewDetails.Columns.Count + 1; i++)
        {
            worksheet.Cells[1, i] = dataGridViewDetails.Columns[i - 1].HeaderText;
        } 
        for (int i = 0; i < dataGridViewDetails.Rows.Count; i++)
        {
            for (int j = 0; j < dataGridViewDetails.Columns.Count; j++)
            {
                if (j == 3)
                {
                    worksheet.Cells[i + 2, j + 1] = dataGridViewDetails.Rows[i].Cells[j].Value.ToString().Split (' ')[0];

                }
                else
                {
                    worksheet.Cells[i + 2, j + 1] = dataGridViewDetails.Rows[i].Cells[j].Value.ToString();
                }
            }
        }

    }

这是 GridView 的图像

这是从 GridView 导出后的 Excel 数据图像

正如您在代码中看到的,我正在以字符串格式导出每个数据,因此 Excel 单元格类型应该没有问题。但数据格式仍然可以转换。 我在做什么错?

这里有两件非常不同的事情:

  1. 日期时间的存储方式
  2. 日期时间的显示方式

.NET端

.NET 将 DateTime 存储为自 Unix Epoch 开始以来的滴答数。 每个其他属性和字符串表示都是对这个值的解释。

.NET 通过从 Windows 中提取用户文化设置来显示任何数值 - 包括日期时间。 这是一个非常有用的功能,因为这是我们通常不必注意的一个重要部分。

Excel 端

旧的 Excel 格式使用十进制或浮点值。 十进制分隔符之前的部分是自 0-jan-1900 以来的 deys。 它还有一个众所周知的错误,将 1900 年视为闰年。 分隔符后面的部分表示一天中的时间。 但它可能仍然有单独的日期和时间类型(这些已经失宠,因为在实践中几乎毫无用处)。

它如何显示这些值完全取决于您查看它的 Excel 版本及其设置。

我知道我回答这个晚了一年。 我希望它可以帮助任何可能正在寻找类似解决方案的人。

excel中日期的默认格式是根据系统选择的语言确定的。 如果您默认需要 DD-MM-YYYY,则将语言更改为英语(印度)即可解决。

请注意:日期格式将根据打开文件的父系统而变化。 因此,在您的 PC/笔记本电脑中,它可能会显示 DD-MM-YYYY,但是当我在系统中打开相同的文件时,它将是 MM-DD-YYYY,因为我的工作站中设置的语言是英语(美国)。

这是一个老问题; 但是,我将这个答案留在这里,希望对某人有所帮助。

我遇到了与您完全相同的问题。 在墨西哥,我们使用“日/月/年”日期格式。 在 Excel 和其他信息系统中错误解释日期是一个非常普遍的问题,其中“3/6/2020”(墨西哥记法中的 6 月 3 日)在粘贴到 Excel 时被翻译为“6/3/2020”(3 月 6 日)或导出到旧系统。

我有一个将信息导出到 Excel 的 WPF C# 应用程序。 不明确的日期也会出现同样的问题(例如,16/10/2020 总是被正确解释为 10 月 16 日,因为它并不含糊)。 我尝试了与您相同的解决方案,创建一个预先格式化的字符串,然后将其导出。 然而,结果却完全一样。 我认为 Excel 在内部应用与在单元格中键入内容相同的过程,Excel 会尝试确定它是哪种类型的信息(日期、数字、货币等)。因此,通过导出字符串,Excel 仍然尝试了解信息,并确定它是一个日期,然后转换为日期单元格。

我还注意到 Interop 忽略了 Windows 和 Excel 区域设置。 例如,如果我启动 Excel 并直接输入“3/6/2020”,则该信息将被正确解释为日期和正确的日期(2020 年 6 月 3 日)。 但是,通过使用 Interop,将“3/6/2020”写入 Excel 会显示为“6/3/2020”; 将单元格格式更改为“长日期”会显示“2020 年 3 月 6 日”(当然是西班牙语),因此这不仅仅是一个演示问题:日期实际上已更改。 很明显,Excel 在为时已晚时应用区域设置:在解释导出的日期之后。

我认为“正确”的解决方案是通过 Interop 命令配置工作簿的区域设置; 但是,我找到了两个更快更简单的解决方案。 他们两个都工作。

第一个选项:强制 Excel 将日期管理为文本字符串

这是快速而肮脏的解决方案。 一个如此简单以至于看起来很愚蠢的方法:只需在字符串的开头添加一个撇号 (')。 是的,我们在 Excel 中使用了多年的好方法。

DateTime my_date = DateTime.Today;
string my_string_date = my_date.ToString("dd/mm/yyyy");
string my_fixed_date = "'" + my_string_date;
excelsheet.Cells[1, 1] = my_fixed_date;

完毕! Excel 将完全按照您的预期显示日期。 但是,这种方法有一个缺点:单元格包含文本字符串,而不是日期。 更好的解决方案应该将单元格保留为日期; 用户可能希望在公式中使用单元格的数据作为日期值。

第二个选项(我认为最佳解决方案):使用正确的日期格式格式化单元格

在这个解决方案中,实际的日期变量被导出。 但在此之前,单元格会使用与我们希望显示日期的方式相匹配的日期格式进行格式化。 在这种情况下,我们不需要预先格式化的字符串。

DateTime my_date = DateTime.Today;
excelsheet.Cells[1, 1].NumberFormat = “dd/mm/aaaa”;
excelsheet.Cells[1, 1] = my_date;

而已。 在 Visual Studio 2019 中使用 WPF C# 进行测试时,此方法有效。

请注意,我使用的是西班牙日期格式(“dd/mm/aaaa”),因此您可能需要将其更改为 Excel 区域设置可以理解的字符串。 这是解决方案的缺点:它依赖于语言环境。 Excel 倾向于将公式和设置转换为区域语言,这对普通用户来说非常方便,但对程序员来说却是一种痛苦。

另请注意,我在插入值之前更改了单元格格式。 我尝试在插入日期值后应用单元格格式,但没有奏效。

可以通过找到一种以与语言环境无关的方式定义单元格格式的方法来改进第二个解决方案。 如果我找到了怎么做,我会改变答案。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM