导出数据表时如何删除导出为ex​​cel警告

时间:2014-10-06 08:40:15

标签: c# asp.net excel datatable

我有以下代码,数据表已经有数据,我想将它导出到excel。 但是我得到了以下警告,我尝试了xlsx并且它不起作用。 我也尝试了csv,数据不会打开到我需要的列中。

public static void ExportDatatabletoExcel(DataTable dt, List<string> columnNames)
        {
            try
            {
                const string attachment = "attachment; filename=elreport.xls";
                HttpContext.Current.Response.ClearContent();
                HttpContext.Current.Response.AddHeader("content-disposition", attachment);
                HttpContext.Current.Response.ContentType = "application/vnd.ms-excel";
                string tab = "";
                foreach (DataColumn dc in dt.Columns)
                {
                    if (!columnNames.Contains(dc.ColumnName)) continue;
                    HttpContext.Current.Response.Write(tab + dc.ColumnName);
                    tab = "\t";
                }
                HttpContext.Current.Response.Write("\n");
                int i;
                foreach (DataRow dr in dt.Rows)
                {
                    tab = "";
                    for (i = 0; i < dt.Columns.Count; i++)
                    {
                        if(!columnNames.Contains(dt.Columns[i].ColumnName)) continue;
                        HttpContext.Current.Response.Write(tab + dr[i].ToString());
                        tab = "\t";
                    }


                    HttpContext.Current.Response.Write("\n");
                }
                HttpContext.Current.Response.End();
            }
            catch (Exception ex)
            {
                string errorMessage = String.Format("ExportToExcelError: {0}", ex.Message);
                LoggingService.LogError(LoggingCategory.General, ex, errorMessage);
                throw;
            }
        }

错误是:

2 个答案:

答案 0 :(得分:3)

来自This answer

How to suppress the file corrupt warning at Excel download?解决了一些问题。我建议您查看其他一些答案。

  

警报是Excel 2007中名为Extension的新安全功能   强化,确保打开的文件内容匹配   正在尝试的shell命令中指定的扩展类型   打开文件。

     

...

     

此问题仍在调查中,但直到修复才有可能   Office 14给出了代码复杂性和事实的本质   Excel不希望降低安全措施以解决此问题   IE开放行为没有完全理解后果   其他浏览器用户。

此外,this comment可能有所帮助。

  

我认为只有在您使用CSV并另存为XLS时才适用。   但是,如果你构建一个真正的excel文件,那么它应该没问题。   CF9 cfspreadsheet将是你的朋友。 :) - Henry Jun 25&09; 09 23:53

要检查的其他来源:

答案 1 :(得分:3)

有两种可靠的方法可以删除警告。

  1. 使用OpenXML API或EPPlus API构建有效的.xlsx文件(EPPlus更容易实际支持OleDB导入)

  2. 将文件构建为扩展名为.csv的.csv文件,但将内容类型保留为Excel,以便使用Excel打开。但是,您构建文件的方式可能会导致Excel正确读取内容时出现问题,需要解决这个问题:

  3. Excel只有在以某种方式格式化时才能读取CSV。假设您使用Excel for Windows,或者它不会处理外来字符,编码必须是Windows 1252。来自邮政编码等的前导零也需要专门为Excel处理。

      public static class CSVExportUtility
        {
        /// <summary>
            /// Open a datatable in Excel
            /// </summary>
            /// <param name="dt"></param>
            /// <param name="fileName"></param>
            public static void OpenAsCSV(DataTable dt, string fileName)
            {
                CSVExportUtility.OpenAsCSV(DataTableToCSV(dt), fileName); // now open the file
            }   // OpenAsCSV
        /// <summary>
            /// open the content in the browser as a CSV
            /// </summary>
            /// <param name="sbCSVFileData"></param>
            /// <param name="filename"></param>
            public static void OpenAsCSV(StringBuilder sbCSVFileData, string fileName)
            {
                if (HttpContext.Current == null || HttpContext.Current.Response == null)
                    return;
    
                HttpContext.Current.Response.Clear();
                HttpContext.Current.Response.AddHeader(
                    "content-disposition", string.Format("attachment; filename={0}", fileName));
                HttpContext.Current.Response.ContentType = "application/ms-excel";
    
                // This is a little tricky.  Would like to use utf-8 or unicode... but Excel on Windows uses 1252 by default so we need to keep the same so most users can read the file.
                // At some point, we may need to actually convert our text from whatever .NET uses to 1252, but at the moment they seem similar enough that it is okay
                HttpContext.Current.Response.ContentEncoding = Encoding.GetEncoding(1252);
    
                //  render the htmlwriter into the response
                HttpContext.Current.Response.Write(sbCSVFileData.ToString());
                HttpContext.Current.Response.End();
            }
    
    static StringBuilder DataTableToCSV(DataTable dt)
            {
                StringBuilder sb = new StringBuilder();
                foreach (DataColumn dc in dt.Columns)
                {
                    if (dc == dt.Columns[dt.Columns.Count - 1])
                        CSVExportUtility.AddFieldForCSV(dc.ColumnName, sb, false, true);
                    else
                        CSVExportUtility.AddFieldForCSV(dc.ColumnName, sb, true, false);
                }
                foreach (DataRow dr in dt.Rows)
                {
                    foreach (DataColumn dc in dt.Columns)
                    {
                        if (dc == dt.Columns[dt.Columns.Count - 1])
                            CSVExportUtility.AddFieldForCSV(FormatDataValue(dr[dc.ColumnName]), sb, false, true);
                        else
                            CSVExportUtility.AddFieldForCSV(FormatDataValue(dr[dc.ColumnName]), sb, true, false);
                    }
                }
                return sb;
            }
    
      static string FormatDataValue(object dv)
            {
                if (dv == null)
                    return null;
                if (dv is DateTime)
                    return ((DateTime)dv).ToShortDateString();
                else
                    return dv.ToString();
            }
    
            /// <summary>
            /// export text to a csv
            /// </summary>
            /// <param name="text"></param>
            /// <param name="sbCSV"></param>
            /// <param name="appendTrailingComma"></param>
            /// <param name="endOfRow"></param>
            public static void AddFieldForCSV(string text, StringBuilder sbCSV, bool appendTrailingComma, bool endOfRow)
            {
                // shouldn't start or end with whitespace, escape quotes
                if (text != null)
                    text = text.Trim().Replace("\"", "\"\"");
    
                // quote field
                int testInt;
                if (text != null && text.Trim().Length > 1 && text.Trim()[0] == '0' && int.TryParse(text.Trim(), out testInt))
                {   // if text is numeric and starts with '0' tell excel to treat as string and not strip the zero. This ONLY works if it's numeric!  Otherwise it fails, example ="a,b" will use 2 cells
                    text = "=\"" + text.Trim() + "\"";
                }
                else
                {
                    text = "\"" + text + "\"";
                }
    
                sbCSV.Append(text);
                if (appendTrailingComma)
                    sbCSV.Append(",");
                if (endOfRow)
                    sbCSV.AppendLine();
            }
    }
    

    如果您要导出GridView而不是DataTable,那么解释如下: http://atakala.com/Browser/Item.aspx?user_id=amos&dict_id=2325 ;大部分代码都是类似的(CSVExportUtility方法)