生成的 Excel 文件在不同系统中显示不同的日期值(Asp.net Web 应用程序)
Posted
技术标签:
【中文标题】生成的 Excel 文件在不同系统中显示不同的日期值(Asp.net Web 应用程序)【英文标题】:Generated Excel file showing date value differently in different systems ( Asp.net web application) 【发布时间】:2019-09-28 23:07:51 【问题描述】:我有 asp.net 网络应用程序,它向带有 .xls 附件的用户发送电子邮件,这个文件有几个显示日期的列,所以当用户在这些系统中下载这个 excel 文件时,只有系统设置在dd-mm-yyyy 格式的日期显示正确,对于系统设置不是 dd-mm-yyyy 格式的所有其他用户,日期列显示不正确。
知道如何解决此问题,要求是使日期列以 dd-mm-yyyy 格式显示,而与用户时间设置无关
我正在使用以下代码行通过电子邮件发送 .xls 文件
using (StreamReader stRDR = new StreamReader(Server.MapPath("~/2.1.3.2-B-MAILER.html")))
sHTMLbody = stRDR.ReadToEnd();
sHTMLbody = sHTMLbody.Replace("NAME", sSalesL2name.ToString());
sHTMLbody = sHTMLbody.Replace("MESSAGEBODY", sMsgBodyTemplate);
var dtServer = DateTime.Now;
string FileName = "SalesL2_" + sSalesL2sapcode + ".xls";
String sPath = Path.GetTempPath() + FileName;
//String sPath = Path.GetTempPath() + sL3sapcode.ToString() + dtServer.ToString("_yyyy-MM-dd__HH-mm-ss") + ".xls";
FileInfo FI = new FileInfo(sPath);
StringWriter stringWriter = new StringWriter();
HtmlTextWriter htmlWrite = new HtmlTextWriter(stringWriter);
// For the below line to work, we need [override void VerifyRenderingInServerForm as part of class]
GridView gvTemp = new GridView();
gvTemp.AllowPaging = false;
gvTemp.DataSource = dtResult;
gvTemp.DataBind();
gvTemp.RenderControl(htmlWrite);
gvTemp = null;
System.IO.StreamWriter vw = new System.IO.StreamWriter(sPath, true);
stringWriter.ToString().Normalize();
vw.Write(stringWriter.ToString());
vw.Flush();
vw.Close();
Attachment attXLS = new Attachment(FI.FullName);
//"application/vnd.ms-excel";
// Send Email
// Create new Mail Object
objMail = new MailMessage(); // Create new Mail Object
objMail.From = new MailAddress("ersdocumenttracking@hcl.com");
**Stored proc**
select distinct t1.[Project code],t1.[Project Description],t1.[Start Date],
t1.[End Date],t1.[Customer],t1.[Customer Name],t1.[Customer Group],
[AM Sales SAPID],[AM Sales Name],[L3 Sales SAPID],[L3 Sales Name],[L2 sales SAPID],[L2 sales Name],
t1.[Proj Category Description],t1.[DU Desc (L4)],t1.[SDU Name (L3)],
t1.[PM Code],t1.[PM Name],t1.[VBDU Desc (L2)],t1.[SPM Code],t1.[SPM Name],t1.[DUH Code],t1.[DUH Name],
t1.[SDUH Code],t1.[SDUH Name],[VBDUH Code],[VBDUH Name],[Geo Reg Name],[Customer SOW],t1.[MSA],
[MSA Start Date],[MSA End Date],[SOW Start Date],[SOW End Date],[Document applicability],
[Avg Rev based on AMJ '18 PP (in $K)] [Avg Rev based on last quarter PP (in $K)],[UAR $K],
[MSA RAG check],[SOW RAG check],
[PONumber],[POValidFrom],[POValidTo],[Balance in $K],
[PO RAG check],[PO Insufficient flag],[MSA Documents remarks], [SOW Documents remarks],
[PO Documents remarks]
from [tbl_MSA_SOW] as t1 left join [tbl_PO] as t2
on t1.[Project code] = t2.[Project Code]
inner join [tbl_Sales_mapping] as t3
on t1.[Project code]=t3.[Project code]
where (t1.[MSA RAG check]=@RagValue or t1.[SOW RAG check]=@RagValue
or t2.[PO RAG check]=@RagValue)
and t3.[L2 sales SAPID]=@sapid and t3.[AM Sales Name] !='-'
【问题讨论】:
开始使用专门的库来创建 Excel 文件,例如 EPPlus。您现在所做的只是创建一个扩展名为 .xls 的 HTML 页面。 【参考方案1】:你不应该这样做。如果您要发送 Excel 表格,则应向用户显示日期。让excel根据用户的系统设置显示日期。不要预设格式。如果您这样做,那么用户将日期作为字符串获取,并且必须对其进行转换才能对数据执行任何有用的操作。 还有一点,有什么理由,为什么要发送 xls 而不是 xlsx?鉴于这是通过电子邮件进行的,用户会更乐意下载 xlsx 文件,因为它们保证不包含宏。 Xls 被认为更危险,许多电子邮件客户端阻止用户打开 xls,正是出于这个原因。
编辑
看了你的代码,我更清楚地理解了这个问题。您制作的不是真正的 Excel 电子表格;它只是一个添加了 .xls 扩展名的文本文件。
要了解区别,请创建一个新的 Excel 电子表格,输入一些示例数据,然后将其保存为 xls(Excel 97 格式)。现在在记事本中打开文件,看看你得到了什么。现在打开您通过代码生成的文件。
这里发生了什么? Excel 足够聪明地认识到,虽然您生成的文件具有错误的扩展名(即文件的内容不是 xls 所需的内容),但它具有可以在电子表格中显示的数据,因此可以方便地加载它。
将扩展名更改为 xlsx 没有帮助。
您有两个选择:1) 诚实并使用适合您生成文件格式的扩展名(*.txt、*.csv 等)或 2) 您需要将 Excel 工作簿生成为本机 Excel 文件。
如果您选择后一种方式,则有多种选择:1) 使用 Office 互操作性库,2) 使用第三方 Excel 库(其中一些是免费的 - 请使用 Google c# Excel 库)或 3) 生成您自己的库。我个人不得不选择 3),因为 1) 的问题是 Office 需要安装在 Web 服务器上,而 2) 它要么花钱,要么意味着使用免费软件,我的雇主通常不乐意这样做。
如果你想做 3) 我可以给你一些帮助。我推荐的第一步是在 Excel 中创建一个示例 xlsx 文件并保存。然后将资源管理器中的扩展名更改为 .zip(是的!!)并解压缩。然后检查内容。你会发现它很有趣,但那是你需要创造的。这并不容易,但可以使用 .Net 中的内置函数来完成。
编辑 2)
如果您选择走 csv 路线(我不确定您这里的内容是否真的是 csv,您需要打开生成的文件才能确定),那么它目前仅适用于具有 dd 的系统-mm-yyyy 日期格式。要使其适用于任何语言环境,您需要采用 ISO 8601 格式的日期(即 yyyy-mm-dd)。为此,您有两个选择。首先,在生成数据时更改您的存储过程以格式化日期,因此:
SELECT CONVERT(varchar(10), your_date, 126) AS your_date FROM your_table;
(请注意,您应该为输出列提供别名,否则它会得到 Expr1 等)。 其次,您可以在检索数据后将 DataColumn 添加到 DataTable 中,逐步检查 DataTable 的行并将新列分配为预先存在的日期列的 ISO 8601 格式版本,然后删除预先存在的日期列。在生成文本输出之前执行所有这些操作。
【讨论】:
ok 乔纳森明白了你的意思,你的意思是说,根据用户系统设置,日期列会出现,是的,如果它显示正确,那很好,但在我们的例子中,用户不是dd-mm-yyyy 它没有正确显示我的意思是日期列,正如你所说的不显示格式,所以我需要在代码中删除什么你能帮我吗 您没有显示任何创建电子表格的代码,只有创建文件名的代码。也请考虑我关于 xlsx 的观点。 SO 不是免费的编码网站。我们在这里为您提供帮助,但不是为您编写代码。请查看提问指南。 是的,乔纳森,谢谢,我明白,excel 文件中的数据是从存储过程生成的,该存储过程具有列开始日期和结束日期,并且用于这些列的数据类型是日期时间。 好的,乔纳森感谢您对上述问题的详细分析,我会对其进行调查,如果需要任何帮助,我会通知您,再次感谢您的宝贵时间。 嗨乔纳森,这里有个疑问,所以如果我在代码中将扩展名更改为 .csv,无论系统中的时间格式如何,datetime 列都会在任何系统中正确显示日期。以上是关于生成的 Excel 文件在不同系统中显示不同的日期值(Asp.net Web 应用程序)的主要内容,如果未能解决你的问题,请参考以下文章