1

当我将 gridview 导出到 excel 时,缺少最后一个数据。这是我导出数据的代码。

private void ToCsV(DataGridView dGV, string filename)
    {
        string stOutput = "";
        // Export titles:
        string sHeaders = "";

        for (int j = 0; j < dGV.Columns.Count; j++)
            sHeaders = sHeaders.ToString() + Convert.ToString(dGV.Columns[j].HeaderText) + "\t";
        stOutput += sHeaders + "\r\n";
        // Export data.
        for (int i = 0; i < dGV.RowCount - 1; i++)
        {
            string stLine = "";
            for (int j = 1; j < dGV.Rows[i].Cells.Count; j++)
                stLine = stLine.ToString() + Convert.ToString(dGV.Rows[i].Cells[j].Value) + "\t";
            stOutput += stLine + "\r\n";
        }
        Encoding utf16 = Encoding.GetEncoding(1254);
        byte[] output = utf16.GetBytes(stOutput);
        FileStream fs = new FileStream(filename, FileMode.Create);
        BinaryWriter bw = new BinaryWriter(fs);
        bw.Write(output, 0, output.Length); //write the encoded file
        bw.Flush();
        bw.Close();
        fs.Close();
    }

这是按钮的代码。

SaveFileDialog sfd = new SaveFileDialog();
        sfd.Filter = "Excel Documents  (.xls)|*.xls";
        sfd.FileName = "";
        if (sfd.ShowDialog() == DialogResult.OK)
        {
            //ToCsV(dataGridView1, @"c:\export.xls");
            ToCsV(gvHistory, sfd.FileName); // Here dataGridview1 is your grid view name 
        }
4

3 回答 3

3

你有

for (int i = 0; i < dGV.RowCount - 1; i++)
{
  ...
}

因此,您从导出中明确排除了最后一行。
更改i < dGV.RowCount - 1i < dGV.RowCount


此外,代码:

string stLine = "";
for (int j = 1; j < dGV.Rows[i].Cells.Count; j++)
  stLine = stLine.ToString() + Convert.ToString(dGV.Rows[i].Cells[j].Value) + "\t";
stOutput += stLine + "\r\n";

基本上是何时使用StringBuilder而不是string. 随着您获得更多行,它会逐渐变慢。更好的版本是:

StringBuilder sbOutput = new StringBuilder();

for (int j = 0; j < dGV.Columns.Count; j++)
   sbOutput.AppendLine(Convert.ToString(dGV.Columns[j].HeaderText) + "\t");
for (int i = 0; i < dGV.RowCount - 1; i++)
{
  for (int j = 1; j < dGV.Rows[i].Cells.Count; j++)
    sbOutput.Append(Convert.ToString(dGV.Rows[i].Cells[j].Value) + "\t");
  sbOutput.AppendLine();
}
Encoding utf16 = Encoding.GetEncoding(1254);
byte[] output = utf16.GetBytes(sbOutput.ToString());

接下来,在迭代集合时,您可以使用该for(int i=0; i < length; i++)模式,但通常最好简单地使用foreach. 这样您就可以确定它将循环所有行 - 这就是 foreach 根据定义所做的。额外的好处是循环变量有一个更好的名称,即row代替dGV.Rows[i]. 所以代码将是:

foreach(var column in dGV.Columns)
   sbOutput.AppendLine(Convert.ToString(column.HeaderText) + "\t");

foreach (var row in dGV.Rows)
{
  foreach (var cell in row.Cells)
    sbOutput.Append(Convert.ToString(cell.Value) + "\t");
  sbOutput.AppendLine();
}
Encoding utf16 = Encoding.GetEncoding(1254);
byte[] output = utf16.GetBytes(sbOutput.ToString());

这更具可读性,并且不太容易出现愚蠢的“一个接一个”错误。


最后,一个吹毛求疵的点:该方法被调用ToCsv,但值不是逗号分隔的,而是制表符分隔的值。这并不是什么大问题,因为不知何故,“CSV”一词已经演变为任何格式,其中行位于单独的行上,并且行中的值以某种方式分开,但制表符分隔的值仍然是一回事。

于 2013-08-14T08:07:37.263 回答
0

尝试<=在循环中使用而不是<

于 2013-08-14T08:08:16.327 回答
0

看起来您正在切断 dGV 中的最后一项。

    // Export data.
    for (int i = 0; i < dGV.RowCount - 1; i++)

应该

    // Export data.
    for (int i = 0; i < dGV.RowCount; i++)
于 2013-08-14T08:08:17.663 回答