简体   繁体   English

导出数据表时如何删除导出到Excel警告

[英]How to remove export to excel warning when exporting datatable

I have the following code, the datatable already has the data and I want to export it to excel. 我有以下代码,数据表已经有数据,我想将其导出到excel。 However I get the following warning, I tried xlsx and it doesnt work. 但是我收到以下警告,我尝试了xlsx,但它不起作用。 I also tried csv, and the data does not open into columns as I need. 我也尝试了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;
            }
        }

Error is: 错误是:

This answer from How to suppress the file corrupt warning at Excel download? 如何在Excel下载时抑制文件损坏警告的 答案 addresses some of the problem. 解决了一些问题。 I recommend checking out some of the other answers as well. 我建议也检查一些其他答案。

The alert is a new security feature in Excel 2007 called Extension Hardening, which ensures that the file content being opened matches the extension type specified in the shell command that is attempting to open the file. 该警报是Excel 2007中的一项新的安全功能,称为扩展强化,可确保打开的文件内容与尝试打开文件的shell命令中指定的扩展名类型匹配。

... ...

This issue is still being investigated, but a fix is not likely until Office 14 given the nature of the complexity of the code, and the fact that Excel does not want to lower the security measure to workaround IE open behaviors without a full understanding of the consequences for other browser users. 这个问题仍在调查中,但是鉴于Office 14的代码复杂性,并且在不完全了解IE开放行为的情况下Excel不想降低安全措施来解决IE开放行为的事实,直到Office 14才可能解决此问题。对其他浏览器用户的后果。

Also, this comment might help. 此外, 此评论可能会有所帮助。

I think that only applies if you're using CSV and save as XLS. 我认为这仅适用于使用CSV并另存为XLS的情况。 However, if you construct a real excel file, then it should be fine. 但是,如果您构建一个真正的excel文件,那应该没问题。 CF9 cfspreadsheet will be your friend. CF9 cfspreadsheet将成为您的朋友。 :) – Henry Jun 25 '09 at 23:53 :) –亨利09年6月25日在23:53

Other sources to check: 其他要检查的资源:

There are two sure ways to remove the warning. 有两种清除警告的肯定方法。

  1. Build a valid .xlsx file using the OpenXML API or EPPlus API (EPPlus is easier and actually supports OleDB imports) 使用OpenXML API或EPPlus API构建有效的.xlsx文件(EPPlus更容易,并且实际上支持OleDB导入)

  2. Build the file as .csv with .csv extension, but leave the content-type as Excel so that it opens with Excel. 将文件构建为扩展名为.csv的.csv,但将内容类型保留为Excel,以便使用Excel打开。 However, the way you are building the file you may have issues with Excel reading the content correctly, which needs to be addressed: 但是,在构建文件的方式上,Excel可能无法正确读取内容,这需要解决:

Excel can only read CSV if it is formatted in certain ways. 如果以某些方式设置了格式,Excel只能读取CSV。 Also the encoding has to be windows 1252 assuming you are using Excel for windows, or it won't handle foreign chars. 假设您使用Excel for Windows,编码也必须是Windows 1252,否则它将无法处理外来字符。 Also leading zeros from zip codes etc. need to be dealt with specially for Excel. 另外,邮政编码等中的前导零也需要专门针对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();
        }
}

If you are looking to export a GridView instead of a DataTable, that explanation is at: http://atakala.com/Browser/Item.aspx?user_id=amos&dict_id=2325 ; 如果您要导出GridView而不是DataTable,请访问以下说明: http : //atakala.com/Browser/Item.aspx? user_id=amos&dict_id= 2325 ; much of the code is similar (CSVExportUtility methods) 许多代码是相似的(CSVExportUtility方法)

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

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