0

当我有一个从 SQL 表读取数据并从中生成 EXCEL 报告的 ASP.NET C# 代码/程序时,如何向 EXCEL/CSV 单元格添加额外的单引号字符?所以产生的数字不是科学价值,它会是准确的(它是一个额外的单引号字符到将有数据的单元格)。我需要在数据之前添加单引号,但是添加后,单引号本身不会显示,而是会显示确切的数字。

问题在下图中,从 SQL Result 来看,它是一个准确的数字,但是当使用代码时,它会被四舍五入到科学值。图片: http ://photoadder.com/show-image.php?id=0ca30b7f4ba55fe359c889af62a278a4 (点击放大)

当我将单引号输入到我自己的 excel 中时,这就是结果。图片:http ://photoadder.com/show-image.php?id=48366a8093afc8555bcf7c990fc3648e

这是我的部分代码

public DataTable GetData()
{
   var dataTable = new DataTable();

   SqlConnection conn = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["connectionString"].ConnectionString);
   conn.Open();
   string query = "select * from table abc";

   SqlCommand cmd = new SqlCommand(query, conn);

   DataTable t1 = new DataTable();
   using (SqlDataAdapter a = new SqlDataAdapter(cmd))
   {
       a.Fill(t1);
   }
   return t1;
}
#endregion


protected void btnGenerateReport_Click(object sender, EventArgs e)
{
    System.Diagnostics.Debug.WriteLine("PLaccount system on click");

    var dataTable = GetData();

    StringBuilder builder = new StringBuilder();
    List<string> columnNames = new List<string>();
    List<string> rows = new List<string>();

    foreach (DataColumn column in dataTable.Columns)
    {
        columnNames.Add(column.ColumnName);
        if (column.ColumnName.ToString() == "PL_ACCOUNT_NUMBER")
        {

            System.Diagnostics.Debug.WriteLine("PLaccount system match");

        }
    }

    builder.Append(string.Join(",", columnNames.ToArray())).Append("\n");

    foreach (DataRow row in dataTable.Rows)
    {
        List<string> currentRow = new List<string>();

        foreach (DataColumn column in dataTable.Columns)
        {
            object item = row[column];

            currentRow.Add(item.ToString());
        }

        rows.Add(string.Join(",", currentRow.ToArray()));
    }

    builder.Append(string.Join("\n", rows.ToArray()));

    Response.Clear();
    Response.ContentType = "text/csv";
    Response.AddHeader("Content-Disposition", "attachment;filename=myfilename.csv");
    Response.Write(builder.ToString());
    Response.End();
4

1 回答 1

0

这是 Excel 导入 CSV 文件方式的长期问题。由于 CSV 文件不包含有关数据类型的任何信息,Excel 会根据字符串值进行一些猜测。当您的字符串值看起来像数字但不应该以这种方式解释时,这尤其令人烦恼……例如需要保留这些 0 的前导 0 的电话号码。

大多数导入 CSV 的应用程序可以识别某些字符串引用,例如将可能被误解为其他内容的字符串(包括嵌入逗号的字符串)包含在一对双引号中。Excel 在导入过程的第一部分处理此问题,因此您可以使用它将逗号放在字符串值中。不幸的是,它在开始解释值之前丢弃了双引号。

(我可以高兴地扼杀为此编写 Excel CSV 导入器的人。)

幸运的是,您可以在字符串值的开头使用单引号字符来鼓励 Excel 将其视为字符串,而不是尝试将其解释为数字。这在 CSV 中的工作方式与在 Excel 中的工作方式相同。

这是您的 CSV 中的(部分)行:

701,888888001074709,XXXXXXXXXXXXXXXXXXXX837659,2/27/2013 12:00:00 AM,...

假设您只想将第二个值视为字符串,则需要更改输出方法以生成以下内容:

701,'888888001074709,XXXXXXXXXXXXXXXXXXXX837659,2/27/2013 12:00:00 AM,...

Excel 将正确导入数据,但随后会隐藏单引号字符,就像您以这种方式在单元格中键入数据一样。对单元格的引用将获得单引号等之后的字符。

既然我已经解释了你为什么需要这样做,那么你应该弄清楚如何去做。

如果您尝试编写通用DataTable导出器,而不必指定需要引用的列,则需要执行以下操作之一:

  1. 检查每一列的数据类型,并在每一列字符串前加上一个单引号(快速简单但不美观的选项)

  2. 对于每个字符串列的值,请尝试将其解析为数字,并且如果可行,则仅在前面加上一个单引号。

  3. 传入一个可选的列列表(按名称或索引)来引用。

在这三个中,提供一个可选的列列表来特别处理是我的偏好。

如果您不尝试通用解决方案,请尝试以下操作:

    foreach (DataRow row in dataTable.Rows)
    {
        List<string> currentRow = new List<string>();
        foreach (DataColumn column in dataTable.Columns)
        {
            object item = row[column];

            if (column.Ordinal == 1)
                currentRow.Add("'" + item.ToString());
            else
                currentRow.Add(item.ToString());
        }
        rows.Add(string.Join(",", currentRow.ToArray()));
    }
于 2013-04-24T06:49:18.410 回答