【问题标题】:ExportToExcel in asp.net在 asp.net 中导出到 Excel
【发布时间】:2013-12-05 18:07:07
【问题描述】:
 Destinations      || DeparturePort  || Count || % of Search ||
 --------------------------------------------------------------
 Caribbean Eastern || FLL,MIA     || 2     || 0.03           ||
 South America     || LIM         || 1     || 0.02           ||

导出到excel的代码如下:

using (System.IO.StreamWriter tempFile = new System.IO.StreamWriter(Response.OutputStream))
{
    string cols = "";

    foreach (DataColumn dc in dt1.Columns)
    {
        cols += dc.ColumnName.ToString() + ",";
    }

    #region Writetofile
    System.Collections.Generic.List<string> fileRows = new System.Collections.Generic.List<string>();

    for (int i = 0; i < dt1.Rows.Count; i++)
    {
        string strToWrite = string.Empty;

        for (int j = 0; j < dt1.Columns.Count; j++)
        {
            if (dt1.Rows[i][j].ToString().IndexOf(',') != 0)
            {
                strToWrite += "\"" + dt1.Rows[i][j].ToString() + "," + "\"";
            }
            else
                strToWrite += dt1.Rows[i][j].ToString() + ",";
        }
        fileRows.Add(strToWrite);
    }
    #endregion

    this.CreateExportFile(cols, fileRows, fileName, string.Empty);
    Response.End();
}

在excel中导出的实际代码如下:

internal void CreateExportFile(string colHeader, List<string> arrL, string fileName, string fileType)
{
    #region New code
    if(arrL != null && arrL.Count > 0)
    {
        Response.ContentType = (fileType == null || fileType == string.Empty) ? "text/csv" : fileType;
        Response.AddHeader("Content-Disposition", "attachment;filename=" + fileName);

        using(System.IO.StreamWriter sw = new System.IO.StreamWriter(Response.OutputStream))
        {
            sw.WriteLine(colHeader);

            for(int i = 0; i < arrL.Count; i++)
                sw.WriteLine(arrL[i]);

            sw.Flush();
        } // using 
        Response.End();
    } // if we have data
    #endregion
}

当 Column 具有单个值时,这可以正常工作。但由于列具有多个值,如 MIA、FLL,它将它们分隔在不同的列中。我可以在此处进行哪些更改?

提前谢谢你。

【问题讨论】:

  • 您需要将值括在引号中,并在必要时转义引号。 CSV 文件没有标准,但包括 Excel 在内的大多数阅读器都支持引号分隔。
  • 再次查看您的代码。 Response.ContentType = text/csv。 csv = 逗号分隔值。因此,当然任何逗号都将充当分隔符。您必须查看带引号的分隔符。
  • Response.ContentType = (fileType == null || fileType == string.Empty) ? "text/csv" : fileType; 您的内容类型是 csv ,它会将您的列值(MIA,FLL) 视为不同的列。

标签: c# asp.net


【解决方案1】:

您可以使用以下使用反射的类,基本上将您的行建模为代码中的一个类,并为每个条目创建一个对象,将您的数据作为列表传递,您的列将是该类中的属性。

对于多个值,您可以创建一个 DeparturePort 类,例如包含列表 FLL、MIA 和返回“FLL,MIA”的 ToString,并且主记录类中的属性将包含 DeparturePort 的实例。

  public class CsvExport<T> where T : class
    {
        /// <summary>
        /// The objects
        /// </summary>
        public List<T> Objects;

        /// <summary>
        /// Initializes a new instance of the <see cref="CsvExport{T}"/> class.
        /// </summary>
        /// <param name="objects">The objects.</param>
        public CsvExport(List<T> objects)
        {
            Objects = objects;
        }

        /// <summary>
        /// Exports this instance.
        /// </summary>
        /// <returns></returns>
        public string Export()
        {
            return Export(true);
        }

        /// <summary>
        /// Exports the specified include header line.
        /// </summary>
        /// <param name="includeHeaderLine">if set to <c>true</c> [include header line].</param>
        /// <returns></returns>
        public string Export(bool includeHeaderLine)
        {

            StringBuilder sb = new StringBuilder();
            //Get properties using reflection.
            IList<PropertyInfo> propertyInfos = typeof(T).GetProperties();

            if (includeHeaderLine)
            {
                //add header line.
                foreach (PropertyInfo propertyInfo in propertyInfos)
                {
                    sb.Append(propertyInfo.Name).Append(",");
                }
                sb.Remove(sb.Length - 1, 1).AppendLine();
            }

            //add value for each property.
            foreach (T obj in Objects)
            {
                foreach (PropertyInfo propertyInfo in propertyInfos)
                {
                    sb.Append(MakeValueCsvFriendly(propertyInfo.GetValue(obj, null))).Append(",");
                }
                sb.Remove(sb.Length - 1, 1).AppendLine();
            }

            return sb.ToString();
        }

        //export to a file.
        /// <summary>
        /// Exports the automatic file.
        /// </summary>
        /// <param name="path">The path.</param>
        public void ExportToFile(string path)
        {
            File.WriteAllText(path, Export());
        }

        //export as binary data.
        /// <summary>
        /// Exports the automatic bytes.
        /// </summary>
        /// <returns></returns>
        public byte[] ExportToBytes()
        {
            return Encoding.UTF8.GetBytes(Export());
        }

        //get the csv value for field.
        /// <summary>
        /// Makes the value CSV friendly.
        /// </summary>
        /// <param name="value">The value.</param>
        /// <returns></returns>
        private string MakeValueCsvFriendly(object value)
        {
            if (value == null) return "";
            if (value is Nullable && ((INullable)value).IsNull) return "";

            if (value is DateTime)
            {
                if (((DateTime)value).TimeOfDay.TotalSeconds == 0)
                    return ((DateTime)value).ToString("yyyy-MM-dd");
                return ((DateTime)value).ToString("yyyy-MM-dd HH:mm:ss");
            }
            string output = value.ToString();

            if (output.Contains(",") || output.Contains("\""))
                output = '"' + output.Replace("\"", "\"\"") + '"';

            return output;

        }
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-12
    • 1970-01-01
    相关资源
    最近更新 更多