当我将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
}
答案 0 :(得分:3)
你有
for (int i = 0; i < dGV.RowCount - 1; i++)
{
...
}
因此,您明确地从导出中排除最后一行
将i < dGV.RowCount - 1
更改为i < 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”已经演变为任何行在单独的行上的格式,并且行中的值以某种方式分开,但仍然,tab - 分离值是一件事。
答案 1 :(得分:0)
尝试在循环中使用<=
而不是<
答案 2 :(得分:0)
看起来你正在切断dGV中的最后一项。
// Export data.
for (int i = 0; i < dGV.RowCount - 1; i++)
应该是
// Export data.
for (int i = 0; i < dGV.RowCount; i++)