2013-08-14 1 views
1

gridview를 내보낼 때 마지막 데이터가 누락되었습니다. 여기 내 데이터를 내보내는 코드가 있습니다.gridview를 내보낼 때 마지막 데이터가 누락되었습니다.

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 
     } 
+1

나쁜 생각해야한다. 둘째,'Stream'과'.Flush'에 쓰는 것처럼,'StringBuilder'를 비우는 것을 잊지 마십시오. 셋째,'RowCount'가 잘못되었으므로'foreach'를 사용하여 카운터를 선택하지 않아도됩니다 ('foreach'도 빠름). 그리고 if (DataGridViewRow.IsNewRow)'를 테스트 할 수 있습니다. 당신의'DataGridView'에있는 blnak entry row –

+0

(int i = 0; i <** dGV.RowCount - 1 **; i ++)은 어떨까요? 그것은 (int i = 0; i <** dGV.RowCount **; i ++) –

답변

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"; 

는 기본적으로 대신 stringStringBuilder를 사용하는 예입니다. 더 많은 행을 얻으면 점진적으로 느려질 것입니다. 컬렉션을 반복 할 때

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가 정의한 것입니다. 루프 변수의 이름이 더 멋지다는 이점이 있습니다 (예 : dGV.Rows[i] 대신 row). 따라서 코드는 다음과 같을 것입니다 :

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()); 

이 방법은 가독성이 좋고 바보 같은 'off-by-one'오류가 적습니다.


마지막으로, 하찮은 일에 속 태우고 점 : 상기 방법은 ToCsv라고하지만, 값은 쉼표로 구분되지 않지만 탭 구분 된 값. 여하튼, "CSV"라는 용어는 행이 별도의 행에 있고 행의 값이 여하튼으로 분리되었지만 여전히 탭으로 구분 된 값이 a 인 경우 모든 형식을 의미하기 때문에 진화하지 않았습니다. 맡은 일.

+0

+1 내 첫 번째 생각 중 하나 : "CSV가 아닙니다 ..." –

0

당신이 DGV의 마지막 항목을 차단하고처럼 보이는 대신 <

0

의 루프에 <=를 사용해보십시오.

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

그래서 첫째, 큰 엉덩이 문자열을 사용`StringBuilder`를 사용하는

// Export data. 
    for (int i = 0; i < dGV.RowCount; i++) 
관련 문제