목차
Pypi로 설치
Install-Package Spire.XLS
관련 링크

C#에서 DataTable을 CSV로 내보내기는 테이블 형식의 데이터를 효율적으로 저장, 공유 또는 분석해야 하는 개발자에게 일반적인 요구 사항입니다. .NET의 DataTable 개체는 행과 열을 메모리에 저장하는 구조화된 방법을 제공하지만, 종종 이 데이터를 Excel, 보고 도구 또는 기타 시스템을 위해 CSV 파일로 변환해야 합니다.
이 튜토리얼은 단계별 지침과 실제 코드 예제를 통해 C#에서 DataTable을 CSV로 내보내는 세 가지 쉬운 방법을 설명합니다. 소규모 데이터 세트로 작업하든 대규모 프로덕션 수준 테이블로 작업하든, 이러한 접근 방식은 C#에서 DataTable을 CSV로 변환하는 작업을 빠르고 안정적으로 수행하는 데 도움이 될 것입니다.
목차
- C#에서 DataTable을 CSV로 내보내는 이유
- 방법 1: StringBuilder를 사용한 수동 C# DataTable에서 CSV로 변환
- 방법 2: StreamWriter를 사용한 대용량 C# DataTable에서 CSV로 내보내기
- 방법 3: Spire.XLS for .NET을 사용하여 C#에서 DataTable을 CSV로 변환
- DataTable을 CSV로 변환하는 방법의 성능 비교
- 어떤 방법을 사용해야 할까요?
- DataTable을 CSV로 변환 시 특수 사례 처리 및 모범 사례
- 결론
- 자주 묻는 질문
C#에서 DataTable을 CSV로 내보내는 이유
C#에서 DataTable을 CSV로 내보내면 몇 가지 주요 이점이 있습니다:
- 범용 데이터 형식 – CSV는 Excel, Google Sheets, 데이터베이스 및 많은 응용 프로그램에서 지원됩니다.
- 가독성 및 단순성 – JSON이나 XML과 달리 CSV는 사람이 읽을 수 있고 수동으로 편집하기 쉽습니다.
- 원활한 통합 – 많은 엔터프라이즈 응용 프로그램, CRM 및 보고 도구가 CSV 파일을 허용합니다.
- 빠른 성능 – CSV 생성은 가볍고 효율적입니다.
- 크로스 플랫폼 호환성 – CSV 파일은 모든 시스템에서 열고 처리할 수 있습니다.
방법 1: StringBuilder를 사용한 수동 C# DataTable에서 CSV로 변환
StringBuilder를 사용하여 C#에서 DataTable을 CSV로 수동으로 내보내면 형식 지정 및 이스케이프 규칙을 완벽하게 제어할 수 있으므로 중소 규모 데이터 세트에 이상적입니다.
StringBuilder를 사용하여 C#에서 DataTable을 CSV로 변환하는 단계
- 소스(데이터베이스, API 또는 수동)에서 DataTable을 생성하거나 가져옵니다.
- CSV 콘텐츠를 저장할 StringBuilder를 초기화합니다.
- DataTable.Columns를 반복하여 열 헤더를 추가합니다.
- DataTable 행을 반복하고 각 셀의 값을 추가합니다.
- 쉼표, 따옴표 또는 줄 바꿈과 같은 특수 문자를 이스케이프 처리합니다.
- File.WriteAllText를 사용하여 최종 문자열을 CSV 파일에 씁니다.
예제 코드
using System;
using System.Data;
using System.IO;
using System.Text;
namespace DataTableToCSV
{
internal class Program
{
static void Main(string[] args)
{
// -------------------------------
// 1단계: DataTable 생성
// -------------------------------
DataTable table = new DataTable("Employees");
// 열 정의: ID, Name, Department, Salary, JoinDate, Email
table.Columns.Add("ID", typeof(int));
table.Columns.Add("Name", typeof(string));
table.Columns.Add("Department", typeof(string));
table.Columns.Add("Salary", typeof(decimal));
table.Columns.Add("JoinDate", typeof(DateTime));
table.Columns.Add("Email", typeof(string));
// 더 풍부한 데이터로 샘플 행 추가
table.Rows.Add(1, "Alice Johnson", "HR", 60000, new DateTime(2019, 3, 15), "alice.johnson@example.com");
table.Rows.Add(2, "Bob Smith", "IT", 75000, new DateTime(2018, 7, 22), "bob.smith@example.com");
table.Rows.Add(3, "Charlie Brown", "Finance", 82000, new DateTime(2020, 1, 10), "charlie.brown@example.com");
table.Rows.Add(4, "Diana Prince", "Marketing", 67000, new DateTime(2021, 5, 5), "diana.prince@example.com");
table.Rows.Add(5, "Ethan Hunt", "Operations", 90000, new DateTime(2017, 9, 30), "ethan.hunt@example.com");
table.Rows.Add(6, "Fiona Gallagher", "IT", 72000, new DateTime(2019, 11, 12), "fiona.gallagher@example.com");
// -------------------------------
// 2단계: DataTable을 CSV로 내보내기
// -------------------------------
string csvPath = "employees.csv";
DataTableToCsv(table, csvPath);
Console.WriteLine($"CSV 파일이 성공적으로 생성되었습니다: {csvPath}");
}
/// <summary>
/// DataTable을 CSV 파일로 변환합니다.
/// </summary>
/// <param name="dt">내보낼 DataTable</param>
/// <param name="filePath">CSV 파일이 저장될 경로</param>
public static void DataTableToCsv(DataTable dt, string filePath)
{
// StringBuilder를 사용하여 CSV 콘텐츠를 효율적으로 빌드합니다.
StringBuilder sb = new StringBuilder();
// -------------------------------
// 1단계: 열 헤더 추가
// -------------------------------
for (int i = 0; i < dt.Columns.Count; i++)
{
sb.Append(dt.Columns[i].ColumnName);
if (i < dt.Columns.Count - 1) sb.Append(","); // 마지막 열을 제외하고 쉼표 추가
}
sb.AppendLine();
// -------------------------------
// 2단계: 행 추가
// -------------------------------
foreach (DataRow row in dt.Rows)
{
for (int i = 0; i < dt.Columns.Count; i++)
{
string value;
// DateTime 열을 "yyyy-MM-dd"로 형식 지정
if (dt.Columns[i].DataType == typeof(DateTime))
{
value = ((DateTime)row[i]).ToString("yyyy-MM-dd");
}
else
{
value = row[i].ToString();
}
// 특수 문자 이스케이프 처리: 쉼표, 따옴표, 줄 바꿈
if (value.Contains(",") || value.Contains("\"") || value.Contains("\n"))
{
value = "\"" + value.Replace("\"", "\"\"") + "\"";
}
sb.Append(value);
if (i < dt.Columns.Count - 1) sb.Append(",");
}
sb.AppendLine();
}
// -------------------------------
// 3단계: CSV 파일 쓰기
// -------------------------------
File.WriteAllText(filePath, sb.ToString(), Encoding.UTF8);
}
}
}
출력 CSV

방법 2: StreamWriter를 사용한 대용량 C# DataTable에서 CSV로 내보내기
대용량 DataTable의 경우 StringBuilder를 사용하면 메모리를 많이 사용할 수 있습니다. StreamWriter를 사용하면 행을 한 줄씩 쓸 수 있어 대용량 데이터 세트에 효율적입니다.
StreamWriter 기반 C# DataTable CSV 내보내기 단계
- 필요한 데이터로 DataTable을 생성하거나 검색합니다.
- 출력 CSV 파일 경로와 원하는 인코딩(예: UTF-8)으로 StreamWriter를 초기화합니다.
- DataTable 열 이름을 사용하여 헤더 행을 씁니다.
- DataTable 행을 반복하고 각 줄을 파일에 씁니다.
- CSV 무결성을 유지하기 위해 특수 문자(쉼표, 따옴표, 줄 바꿈)가 포함된 값을 이스케이프 처리합니다.
- StreamWriter를 닫아 시스템 리소스를 해제합니다.
예제 코드
using System;
using System.Data;
using System.IO;
using System.Text;
namespace DataTableToCSV
{
internal class Program
{
static void Main(string[] args)
{
// -------------------------------
// 1단계: 이 예제를 위한 새 DataTable 생성
// -------------------------------
DataTable table = new DataTable("Products");
// 열 정의: ProductID, ProductName, Category, Price, Stock, LaunchDate
table.Columns.Add("ProductID", typeof(int));
table.Columns.Add("ProductName", typeof(string));
table.Columns.Add("Category", typeof(string));
table.Columns.Add("Price", typeof(decimal));
table.Columns.Add("Stock", typeof(int));
table.Columns.Add("LaunchDate", typeof(DateTime));
// 다양한 제품으로 샘플 행 추가
table.Rows.Add(101, "Laptop Pro 15", "Electronics", 1500.99, 25, new DateTime(2023, 1, 10));
table.Rows.Add(102, "Wireless Mouse", "Accessories", 29.95, 200, new DateTime(2022, 11, 5));
table.Rows.Add(103, "Mechanical Keyboard", "Accessories", 79.99, 150, new DateTime(2022, 12, 1));
table.Rows.Add(104, "4K Monitor", "Electronics", 399.50, 40, new DateTime(2023, 2, 20));
table.Rows.Add(105, "USB-C Hub", "Accessories", 49.99, 300, new DateTime(2022, 9, 18));
table.Rows.Add(106, "Gaming Chair", "Furniture", 259.99, 15, new DateTime(2023, 3, 5));
// -------------------------------
// 2단계: StreamWriter를 사용하여 DataTable을 CSV로 내보내기
// -------------------------------
string csvPath = "products_stream.csv";
DataTableToCsvStream(table, csvPath);
Console.WriteLine($"CSV 파일이 성공적으로 생성되었습니다: {csvPath}");
}
/// <summary>
/// StreamWriter를 사용하여 DataTable을 CSV로 내보냅니다 (대용량 데이터 세트에 효율적)
/// </summary>
/// <param name="dt">내보낼 DataTable</param>
/// <param name="filePath">저장할 CSV 파일 경로</param>
public static void DataTableToCsvStream(DataTable dt, string filePath)
{
// 메모리 효율적인 쓰기(한 줄씩)를 위해 StreamWriter 사용
using (StreamWriter writer = new StreamWriter(filePath, false, Encoding.UTF8))
{
// -------------------------------
// 1단계: 열 헤더 쓰기
// -------------------------------
for (int i = 0; i < dt.Columns.Count; i++)
{
writer.Write(dt.Columns[i].ColumnName);
if (i < dt.Columns.Count - 1)
writer.Write(","); // 마지막 열을 제외하고 쉼표 추가
}
writer.WriteLine();
// -------------------------------
// 2단계: 행 쓰기
// -------------------------------
foreach (DataRow row in dt.Rows)
{
for (int i = 0; i < dt.Columns.Count; i++)
{
string value;
// DateTime을 yyyy-MM-dd로 형식 지정
if (dt.Columns[i].DataType == typeof(DateTime))
{
value = ((DateTime)row[i]).ToString("yyyy-MM-dd");
}
else
{
value = row[i].ToString();
}
// 특수 문자 이스케이프 처리: 쉼표, 따옴표, 줄 바꿈
if (value.Contains(",") || value.Contains("\"") || value.Contains("\n"))
{
value = "\"" + value.Replace("\"", "\"\"") + "\"";
}
writer.Write(value);
if (i < dt.Columns.Count - 1)
writer.Write(",");
}
writer.WriteLine();
}
// StreamWriter는 using 블록이 끝날 때 자동으로 닫힙니다.
}
}
}
}
출력 CSV

방법 3: Spire.XLS for .NET을 사용하여 C#에서 DataTable을 CSV로 변환
프로덕션용 응용 프로그램의 경우 Spire.XLS for .NET과 같은 라이브러리는 C# DataTable을 CSV로 내보내는 안정적이고 효율적인 방법을 제공합니다. 이 라이브러리는 특수 문자, 구분 기호 및 인코딩을 자동으로 처리하여 수동 코딩 노력을 줄이고 일관되고 정확한 출력을 보장합니다.
Spire.XLS for .NET 시작하기
C# 프로젝트에서 Spire.XLS를 사용하려면 NuGet을 통해 설치하십시오:
- Visual Studio에서 프로젝트를 엽니다.
- 도구 -> NuGet 패키지 관리자 -> 솔루션용 NuGet 패키지 관리…로 이동합니다.
- “Spire.XLS”를 검색하고 설치를 클릭합니다.
또는 패키지 관리자 콘솔을 사용하여 신속하게 설치할 수 있습니다:
Install-Package Spire.XLS
설치가 완료되면 DataTable을 CSV로 손쉽게 내보내고, CSV를 Excel로 변환하거나 CSV를 다시 DataTable로 가져오는 등 결과 파일에 대한 추가 작업을 .NET 응용 프로그램 내에서 효율적으로 수행할 수 있습니다.
Spire.XLS 기반 C# Datatable에서 CSV로 내보내기 단계
- 내보낼 데이터로 DataTable을 준비합니다.
- Spire.XLS를 사용하여 Workbook 개체를 생성합니다.
- 워크시트에 DataTable을 삽입합니다.
- 구분 기호와 인코딩을 지정하여 워크시트를 CSV로 저장합니다.
예제 코드
using Spire.Xls;
using System;
using System.Data;
using System.Text;
namespace DataTableToCSV
{
internal class Program
{
static void Main(string[] args)
{
// -------------------------------
// 1단계: 책에 대한 새 DataTable 생성
// -------------------------------
DataTable dt = new DataTable("Books");
// 열 정의: BookID, Title, Author, Genre, Price, PublishDate
dt.Columns.Add("BookID", typeof(int));
dt.Columns.Add("Title", typeof(string));
dt.Columns.Add("Author", typeof(string));
dt.Columns.Add("Genre", typeof(string));
dt.Columns.Add("Price", typeof(double));
dt.Columns.Add("PublishDate", typeof(DateTime));
// 샘플 행 추가
dt.Rows.Add(201, "The Great Gatsby", "F. Scott Fitzgerald", "Classic", 10.99, new DateTime(1925, 4, 10));
dt.Rows.Add(202, "1984", "George Orwell", "Dystopian", 9.99, new DateTime(1949, 6, 8));
dt.Rows.Add(203, "To Kill a Mockingbird", "Harper Lee", "Classic", 12.50, new DateTime(1960, 7, 11));
dt.Rows.Add(204, "The Hobbit", "J.R.R. Tolkien", "Fantasy", 15.75, new DateTime(1937, 9, 21));
dt.Rows.Add(205, "Clean Code", "Robert C. Martin", "Programming", 32.99, new DateTime(2008, 8, 1));
dt.Rows.Add(206, "The Pragmatic Programmer", "Andrew Hunt", "Programming", 29.95, new DateTime(1999, 10, 20));
// -------------------------------
// 2단계: Workbook 생성 및 DataTable 삽입
// -------------------------------
Workbook workbook = new Workbook();
Worksheet sheet = workbook.Worksheets[0];
// 1행 1열부터 시작하여 워크시트에 DataTable 삽입
// 열 헤더 포함
sheet.InsertDataTable(dt, true, 1, 1);
// -------------------------------
// 3단계: 워크시트를 CSV로 저장
// -------------------------------
// 매개변수: 파일 이름, 구분 기호, 인코딩
sheet.SaveToFile("books.csv", ",", Encoding.UTF8);
// 리소스 해제
workbook.Dispose();
}
}
}
출력 CSV

Spire.XLS 사용의 이점
- 특수 문자, 구분 기호 및 인코딩 자동 처리 – 수동 이스케이프 처리가 필요 없습니다.
- CSV 가져오기 및 내보내기 모두 지원하여 다양한 워크플로우에 유연하게 적용할 수 있습니다.
- 프로덕션 수준 코드 단순화 – 수동 방법에 비해 상용구 코드가 적고 오류가 적습니다.
- 대용량 데이터 세트에 대한 확장성 – 수천 개의 행이 있어도 효율적으로 작동합니다.
DataTable을 CSV로 변환하는 방법의 성능 비교
각 접근 방식의 강점과 절충점을 더 잘 이해하기 위해 DataTable을 CSV로 내보낼 때 StringBuilder, StreamWriter 및 Spire.XLS를 나란히 비교했습니다.
| 방법 | 적합 대상 | 성능 | 메모리 사용량 | 코드 복잡성 | 참고 |
|---|---|---|---|---|---|
| StringBuilder | 소규모 데이터 세트(<1만 행) | 중간 | 높음 | 보통 | 출력을 완벽하게 제어할 수 있지만 대용량 파일에는 비효율적입니다. |
| StreamWriter | 대용량 데이터 세트(1만+ 행) | 높음 | 낮음 | 보통 | 한 줄씩 쓰므로 메모리 과부하를 방지합니다. |
| Spire.XLS | 프로덕션 및 엔터프라이즈 | 높음 | 최적화됨 | 낮음 | 이스케이프 처리, 인코딩 및 대용량 데이터 세트를 자동으로 처리합니다. |
어떤 방법을 사용해야 할까요?
비교 표는 기술적인 차이점을 강조하지만, 올바른 방법을 선택하는 것은 데이터 세트 크기, 성능 요구 사항 및 프로덕션 요구와 같은 특정 시나리오에 따라 달라집니다.
- CSV 형식을 완벽하게 제어해야 하고 중소 규모 데이터 세트로 작업하는 경우 StringBuilder를 선택하십시오.
- 대용량 데이터 세트를 내보내고 메모리 효율적인 솔루션을 원한다면 StreamWriter를 선택하십시오.
- 특히 특수 사례를 처리하거나 엔터프라이즈 워크플로우에 통합할 때 프로덕션 준비가 완료되고 안정적이며 유지 관리가 적은 접근 방식이 필요한 경우 Spire.XLS를 선택하십시오.
DataTable을 CSV로 변환 시 특수 사례 처리 및 모범 사례
C#에서 DataTable을 CSV로 내보낼 때는 모범 사례를 따르고 CSV 출력에 영향을 줄 수 있는 몇 가지 특수 사례를 인지하는 것이 중요합니다. 이를 올바르게 처리하면 파일이 깨끗하고 안정적이며 사용하기 쉽도록 보장됩니다.
- 특수 사례 처리
- Null 값 – 누락된 데이터가 CSV를 손상시키지 않도록 DBNull을 빈 문자열이나 자리 표시자로 바꿉니다.
- 사용자 지정 구분 기호 – 데이터에 쉼표가 포함된 경우 혼동을 피하기 위해 ; 또는 탭(\t) 사용을 고려하십시오.
- 특수 문자 – 따옴표, 쉼표 또는 줄 바꿈이 포함된 값은 CSV 무결성을 유지하기 위해 적절하게 이스케이프 처리해야 합니다.
- 인코딩 고려 사항 – 대부분의 시나리오에 UTF-8이 권장되지만 일부 시스템에서는 UTF-16 또는 ANSI가 필요할 수 있습니다.
- 대용량 데이터 세트 – 매우 큰 테이블의 경우 성능 문제를 피하기 위해 파일을 분할하거나 StreamWriter와 같은 메모리 효율적인 방법을 사용하는 것을 고려하십시오.
- 모범 사례
- 플랫폼 및 도구 간 호환성을 위해 UTF-8 인코딩을 고수하십시오.
- 예기치 않은 오류를 방지하기 위해 null, 쉼표, 따옴표 및 여러 줄 값과 같은 특수 사례로 테스트하십시오.
- 올바른 방법 선택 – StringBuilder는 작은 테이블에 적합하고 StreamWriter는 대용량 데이터 세트에 더 좋으며 Spire.XLS는 프로덕션 준비 솔루션에 이상적입니다.
- 다른 사람들이 데이터를 해석하는 방법을 알 수 있도록 CSV 구조를 명확하게 문서화하십시오.
결론
C# DataTable을 CSV로 변환하는 기술을 마스터하는 것은 테이블 형식의 데이터로 작업하는 개발자에게 필수적인 기술입니다. 이 가이드는 소규모 데이터 세트에 StringBuilder 사용, 대용량 테이블을 효율적이고 메모리 친화적으로 처리하기 위해 StreamWriter 사용, 복잡한 시나리오를 자동으로 관리하는 안정적인 프로덕션 준비 솔루션을 위해 Spire.XLS 라이브러리 활용 등 세 가지 실용적인 접근 방식을 다룹니다.
이러한 단계별 예제를 따르면 C# DataTable을 CSV로 변환하는 작업을 자신 있게 수행하여 데이터가 정확하고 공유 가능하며 통합 또는 추가 분석 준비가 되었는지 확인할 수 있습니다.
자주 묻는 질문
Q1: C#에서 DataTable을 CSV로 효율적으로 변환하려면 어떻게 해야 합니까?
A1: 세 가지 방법을 사용할 수 있습니다: 소규모 데이터 세트의 경우 StringBuilder로 수동 변환, 대용량 데이터 세트의 경우 StreamWriter, 프로덕션 준비 솔루션의 경우 Spire.XLS 라이브러리. 각 방법은 쉼표, 따옴표 및 줄 바꿈을 올바르게 처리합니다.
Q2: 대용량 C# DataTable을 CSV로 내보내는 가장 좋은 방법은 무엇입니까?
A2: 대용량 데이터 세트의 경우 StreamWriter가 권장됩니다. 메모리 사용량을 줄이면서 한 줄씩 쓰기 때문입니다. Spire.XLS는 프로덕션 환경을 위한 또 다른 신뢰할 수 있는 옵션입니다.
Q3: C#에서 DataTable을 CSV로 내보낼 때 특수 문자와 null 값은 어떻게 처리합니까?
A3: 항상 쉼표, 따옴표, 줄 바꿈을 이스케이프 처리하십시오. null 또는 DBNull 값을 빈 문자열이나 자리 표시자로 바꾸십시오. Spire.XLS를 사용하면 이러한 대부분의 사례가 자동으로 처리됩니다.
Q4: DataTable을 CSV로 내보낼 때 구분 기호와 인코딩을 사용자 지정할 수 있습니까?
A4: 예, 시스템 요구 사항에 따라 ,, ; 또는 \t와 같은 구분 기호를 지정하고 UTF-8, UTF-16 또는 ANSI와 같은 인코딩을 선택할 수 있습니다.
Q5: 수동 또는 StreamWriter 방법 대신 Spire.XLS를 사용해야 하는 이유는 무엇입니까?
A5: Spire.XLS는 이스케이프 처리, 구분 기호 및 인코딩을 자동으로 처리하여 CSV 내보내기를 단순화하고 코드 복잡성을 줄이며 프로덕션 수준 응용 프로그램이나 중대형 데이터 세트에 이상적입니다.
Q6: 내보낸 CSV가 Excel 및 기타 응용 프로그램과 호환되는지 확인하려면 어떻게 해야 합니까?
A6: UTF-8 인코딩을 사용하고 특수 문자를 이스케이프 처리하며 헤더 형식을 일관되게 지정하십시오. Excel 또는 기타 대상 응용 프로그램에서 출력을 테스트하면 호환성 문제를 피하는 데 도움이 됩니다.