【问题标题】:Error message wile trying to open .xls file尝试打开 .xls 文件时出现错误消息
【发布时间】:2017-10-02 03:10:58
【问题描述】:

我正在动态创建一个 Excel 文件,以便在电子邮件中将其作为附件发送。下面提供了相关代码sn-p(这是一个控制台应用程序)

public static void SendEmailWithExcelAttachment(DataTable dt)
{
  try
  {
     string smptHost = smptTuple.Item1;
     MailMessage mailMsg = new MailMessage();
     .............................................
    .............................................
    byte[] data = GetData(dt);

    //save the data to a memory stream
    System.IO.MemoryStream ms = new System.IO.MemoryStream(data);

   mailMsg.Attachments.Add(new System.Net.Mail.Attachment(ms, attachmentName, "application/vnd.ms-excel"));

    ....................................
    ....................................

 //send email
 smtpClient.Send(mailMsg); }
 catch (Exception ex)
  {
      throw ex;
   }
}

private static byte[] GetData(DataTable dt)
{
            string strBody = DataTable2ExcelString(dt);
            byte[] data = Encoding.ASCII.GetBytes(strBody);
            return data;
}

private static string DataTable2ExcelString(System.Data.DataTable dt)
{

            string excelSheetName = "Sheet1";
            StringBuilder sbTop = new StringBuilder();
            sbTop.Append("<html xmlns:o=\"urn:schemas-microsoft-com:office:office\" xmlns:x=\"urn:schemas-microsoft-com:office:excel\" ");
            sbTop.Append("xmlns=\" http://www.w3.org/TR/REC-html40\"><head><meta http-equiv=Content-Type content=\"text/html; charset=windows-1252\">");
            sbTop.Append("<meta name=ProgId content=Excel.Sheet ><meta name=Generator content=\"Microsoft Excel 9\"><!--[if gte mso 9]>");
            sbTop.Append("<xml><x:ExcelWorkbook><x:ExcelWorksheets><x:ExcelWorksheet><x:Name>" + excelSheetName + "</x:Name><x:WorksheetOptions>");
            sbTop.Append("<x:Selected/><x:ProtectContents>False</x:ProtectContents><x:ProtectObjects>False</x:ProtectObjects>");
            sbTop.Append("<x:ProtectScenarios>False</x:ProtectScenarios></x:WorksheetOptions></x:ExcelWorksheet></x:ExcelWorksheets>");
            sbTop.Append("<x:ProtectStructure>False</x:ProtectStructure><x:ProtectWindows>False</x:ProtectWindows></x:ExcelWorkbook></xml>");
            sbTop.Append("<![endif]-->");
            sbTop.Append("</head><body><table>");

            string bottom = "</table></body></html>";


            StringBuilder sbHeader = new StringBuilder();

            //Header
            sbHeader.Append("<tr>");
            for (int i = 0; i < dt.Columns.Count; i++)
            {
                sbHeader.Append("<td>" + dt.Columns[i].ColumnName + "</td>");
            }
            sbHeader.Append("</tr>");

            //Items
            for (int x = 0; x < dt.Rows.Count; x++)
            {
                sbHeader.Append("<tr>");
                for (int i = 0; i < dt.Columns.Count; i++)
                {
                    sbHeader.Append("<td>" + dt.Rows[x][i] + "</td>");
                }
                sbHeader.Append("</tr>");
            }

            string data = sbTop.ToString() + sbHeader.ToString() + bottom;

            return data;
}

这可行,但是当我尝试从附件打开 excel 文件时,我收到:

我检查了在SO Post 中找到了一些解决方案,但无法使其正常工作。我试过&lt;x:DisplayAlerts&gt;False&lt;/x:DisplayAlerts&gt;,但没有成功。

【问题讨论】:

  • 手动构建它的用例是什么?这种创建方式有必要吗?
  • Excel 文件是二进制文件(XLS 文件的前 8 字节签名为D0 CF 11 E0 A1 B1 1A E1),因此不能简单地使用 XML 或 JSON 等文本模式构建 Excel 数据。您可以尝试创建一个使用Excel.Application 实例的方法,迭代DataTable 填充Excel 单元格,然后保存为XLS 文件并作为邮件附件发送。

标签: c# excel console


【解决方案1】:

如果您要创建和发送的文件不必完全采用“.xls”格式..如果您对“.xlsx”格式感到满意...我想您可能想尝试使用@987654321 @图书馆,正如提到的Here。正如我所说,您必须使用“.xlsx”(您可以使用其他 excel 格式,但在打开文件时会收到有关文件格式的相同消息)。因此,您可以使用DataTable 作为源在 EPPlus 的临时文件夹中创建 Excel 文件,并通过电子邮件发送临时文件......例如:

public static void SendEmailWithExcelAttachment(DataTable dt)
    {
        try
        {
            string smptHost = smptTuple.Item1;
            MailMessage mailMsg = new MailMessage();

            string temp = Path.GetTempPath(); // Get %TEMP% path
            string file = "fileNameHere.xlsx";
            string path = Path.Combine(temp, file); // Get the whole path to the file

            FileInfo fi = new FileInfo(path);
            using (ExcelPackage pck = new ExcelPackage(fi))
            {
                ExcelWorksheet ws = pck.Workbook.Worksheets.Add("Table");
                ws.Cells["A1"].LoadFromDataTable(dt, true);
                pck.Save();
            }
            mailMsg.Attachments.Add(new System.Net.Mail.Attachment(path, "application/vnd.ms-excel"));
            try
            {
                //send email
                smtp.Send(mailMsg);
            }
            catch (Exception)
            {
                //do smth..
            }
            finally
            {
                File.Delete(path);
            }
        }
        catch (Exception ex)
        {
            throw ex;
        }
    }

我创建了一个简单的数据表,以“.xlsx”格式发送给自己,并且能够在没有任何“格式警告”的情况下打开它。我希望这会有所帮助。

【讨论】:

    【解决方案2】:

    警告由 MS Excel 应用程序显示,因为您的文件不是真正的 Excel 文件。它是带有 XLS 扩展名的 HTML。 XLS 文件是二进制文件。 MS Excel 识别 HTML 文件,并在其电子表格网格中显示该文件。

    MS Excel 会针对来自电子邮件或互联网等外部来源的文件显示安全警告。

    最好的解决方案是使用 Excel 库,将真实的 Excel 文件保存为 xls(旧 Excel 文件格式)或 xlsx(新 Excel 文件格式)。

    您可以在NPOIEPPlus 等免费库或EasyXLS 等商业库之间进行选择。其中一些只保存 xls 文件,另一些只保存 xlsx 文件,其中一些支持两种文件格式。

    【讨论】:

    • 您可以构建 HTML 表格并将其作为 Excel 流式传输。
    【解决方案3】:

    警告/错误“您尝试打开的文件与文件扩展名指定的格式不同”的解决方案

    原因:

    这是因为在传统的导出到 Excel 方法中,GridView 首先转换为 HTML 字符串,然后将该 HTML 字符串导出到 Excel。因此,最初它不是 Excel 文件,因此 Excel 应用程序会引发警告/错误“您尝试打开的文件的格式与文件扩展名指定的格式不同”。

    解决办法:

    解决此问题的方法是使用 ClosedXML 库,它是 DocumentFormat.OpenXml 库的包装器。

    依赖关系:OpenXml SDK 2.0 必须安装在系统中

    You can get more help here :)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-11-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-06
      • 2013-02-06
      • 2022-01-19
      • 2016-11-03
      相关资源
      最近更新 更多