이 글과 관련된 이전 글
2010/06/08 - C# DataGridView 내용을 Excel로 내보내기
이전에 C#의 DataGridView에서 바로 Excel로 변환하는 글을 포스팅 한적 있습니다. 이번에는 실제 실무에서도 자주 쓰이는 CSV로 변환 하는 방법을 적어보겠습니다. CSV에서는 주로 콤마(,) 를 이용하여 컬럼을 구분하는데, 몇몇 특수한 경우 이를 무시해야할때가 있습니다. 예로 아이템 설명같은 문자열 부분 같은 경우죠. 그럴때에는 " 를 이용해서 그 부분을 감싸주어야 합니다.
( ex. "이 아이템은 캐릭터, 몬스터, 기타 NPC등이 사용합니다." )
또 한가지 염두해야 하는 것이 줄바꿈입니다. CSV 를 툴이나 Excel 등을 이용해 값을 작성하다보면 줄바꿈을 이용할때가 있는데,를 염두하지 않고, 파서를 만들면 전혀 엉뚱한 값을 읽을수 있게 됩니다. ( 줄바꿈을 아예 금지시키는것도 한 방법이기는 합니다 )
// DataGridView의 각행을 읽어 CSV로 변환 // pFileWrite가 CSV 파일 핸들 foreach (DataGridViewRow row in pDGV.Rows) { bool bIsFirstValue = true; foreach (DataGridViewCell cell in row.Cells) { // 첫번째 셀 값이 없다면 이 행은 무시한다 if (bIsFirstValue && null == cell.Value) break; if (!bIsFirstValue) pFilerWriter.Write(","); bIsFirstValue = false; // 빈값 if (null == cell.Value) continue; // Cell 타입에 따라 값을 변환 ( ex. true/false -> 1/0 ) // 기본적으로 Cell 값을 ""로 감싸 놓자 switch (cell.Value.GetType().Name) { case "Boolean": { String strTmp = (true == (bool)cell.Value) ? "1" : "0"; pFilerWriter.Write("\"" + strTmp + "\""); break; } default: { pFilerWriter.Write("\"" + cell.Value.ToString().Replace("\"", "\"\"") + "\""); break; } } } pFilerWriter.WriteLine(); }
// CSV 파서 using ParsedColumn = List<string>; // 컬럼 리스트 using ParsedRow = List<list<string>>; // 로우 리스트 using (StreamReader pFilerReader = new StreamReader(strCSVFileName, Encoding.Default)) { ParsedColumn col = new ParsedColumn(); bool bStartAppend = false; String strItem = ""; String strCSV = pFilerReader.ReadToEnd(); int iStrCSVLenth = strCSV.Length; for (int i = 0; i < iStrCSVLenth; ++i) { // "시작 이후 값들을 다 저장. 문자열을 완성한다. if (bStartAppend && '"' != strCSV[i]) { strItem += strCSV[i]; continue; } // " 시작. 이후 값들을 저장 if (!bStartAppend && '"' == strCSV[i]) { bStartAppend = true; continue; } // "가 끝났다. if (bStartAppend && '"' == strCSV[i]) { bStartAppend = false; continue; } // 콤마가 나오면 조합된 문자열을 하나의 컬럼으로 저장. if (',' == strCSV[i]) { col.Add(strItem); strItem = ""; continue; } // 줄바꿈처리. ""로 감쌓여 있지 않은 상태에서 콤마 이후의 줄바꿈을 열의 끝을 의미한다. if('\r' == strCSV[i]) { col.Add(strItem); strItem = ""; m_ParsedRow.Add(col); ++i; // \n을 건너뜀 continue; } // 파일의 끝 if ('\0' == strCSV[i]) { col.Add(strItem); m_ParsedRow.Add(col); break; } strItem += strCSV[i]; } }