CSV Excel 파일 C# 작성 방법
CSV Excel 파일을 만들기 위한 클래스를 찾고 있습니다.
예상되는 기능:
- 매우 심플한
- 쉼표와 따옴표를 이스케이프하여 Excel로 처리 가능
- 날짜 및 날짜를 시간대별로 내보냅니다.
당신은 이런 일을 할 수 있는 수업을 알고 있나요?
내 욕구에 대한 성찰로 쓴 버전과는 조금 다르다.개체 목록을 csv로 내보내야 했습니다.누군가 미래를 위해 사용하고 싶어할 때를 대비해서.
public class CsvExport<T> where T: class
{
public List<T> Objects;
public CsvExport(List<T> objects)
{
Objects = objects;
}
public string Export()
{
return Export(true);
}
public string Export(bool includeHeaderLine)
{
StringBuilder sb = new StringBuilder();
//Get properties using reflection.
IList<PropertyInfo> propertyInfos = typeof(T).GetProperties();
if (includeHeaderLine)
{
//add header line.
foreach (PropertyInfo propertyInfo in propertyInfos)
{
sb.Append(propertyInfo.Name).Append(",");
}
sb.Remove(sb.Length - 1, 1).AppendLine();
}
//add value for each property.
foreach (T obj in Objects)
{
foreach (PropertyInfo propertyInfo in propertyInfos)
{
sb.Append(MakeValueCsvFriendly(propertyInfo.GetValue(obj, null))).Append(",");
}
sb.Remove(sb.Length - 1, 1).AppendLine();
}
return sb.ToString();
}
//export to a file.
public void ExportToFile(string path)
{
File.WriteAllText(path, Export());
}
//export as binary data.
public byte[] ExportToBytes()
{
return Encoding.UTF8.GetBytes(Export());
}
//get the csv value for field.
private string MakeValueCsvFriendly(object value)
{
if (value == null) return "";
if (value is Nullable && ((INullable)value).IsNull) return "";
if (value is DateTime)
{
if (((DateTime)value).TimeOfDay.TotalSeconds == 0)
return ((DateTime)value).ToString("yyyy-MM-dd");
return ((DateTime)value).ToString("yyyy-MM-dd HH:mm:ss");
}
string output = value.ToString();
if (output.Contains(",") || output.Contains("\""))
output = '"' + output.Replace("\"", "\"\"") + '"';
return output;
}
}
사용 예: (댓글마다 업데이트됨)
CsvExport<BusinessObject> csv= new CsvExport<BusinessObject>(GetBusinessObjectList());
Response.Write(csv.Export());
용서해줘
하지만 공개 오픈 소스 저장소는 코드를 공유하고 기여, 수정, 그리고 "나는 이것을 고쳤다, 나는 저것을 고쳤다"와 같은 추가를 하는 더 나은 방법이라고 생각합니다.
그래서 나는 토픽 스타터의 코드와 모든 추가 사항으로 간단한 git 저장소를 만들었다.
https://github.com/jitbit/CsvExport
저도 몇 가지 유용한 수정 사항을 추가했습니다.모든 사람이 제안을 추가하고, 기여하기 위해 포크할 수 있습니다.포크를 보내주시면 제가 다시 합쳐서 레포에 넣을게요.
추신. Chris에 대한 모든 저작권 공지를 게시했습니다.@크리스, 이 생각에 반대한다면-알려줘, 죽여버릴 거야.
CSV 파일 읽기 및 쓰기에 적합한 또 다른 솔루션은 파일 도움말(오픈 소스)입니다.
스트링을 사용하는 것은 어떨까요?모든 Foreach Loops 대신 가입하시겠습니까?
IEnumerable 확장 방식으로 변환하고 싶은 경우:
public static class ListExtensions
{
public static string ExportAsCSV<T>(this IEnumerable<T> listToExport, bool includeHeaderLine, string delimeter)
{
StringBuilder sb = new StringBuilder();
IList<PropertyInfo> propertyInfos = typeof(T).GetProperties();
if (includeHeaderLine)
{
foreach (PropertyInfo propertyInfo in propertyInfos)
{
sb.Append(propertyInfo.Name).Append(",");
}
sb.Remove(sb.Length - 1, 1).AppendLine();
}
foreach (T obj in listToExport)
{
T localObject = obj;
var line = String.Join(delimeter, propertyInfos.Select(x => SanitizeValuesForCSV(x.GetValue(localObject, null), delimeter)));
sb.AppendLine(line);
}
return sb.ToString();
}
private static string SanitizeValuesForCSV(object value, string delimeter)
{
string output;
if (value == null) return "";
if (value is DateTime)
{
output = ((DateTime)value).ToLongDateString();
}
else
{
output = value.ToString();
}
if (output.Contains(delimeter) || output.Contains("\""))
output = '"' + output.Replace("\"", "\"\"") + '"';
output = output.Replace("\n", " ");
output = output.Replace("\r", "");
return output;
}
}
이 수업에서 수고하셨습니다.심플하고 사용하기 쉽다.내보내기 첫 번째 행에 제목을 포함하도록 클래스를 수정했습니다. 공유하려고 합니다.
용도:
CsvExport myExport = new CsvExport();
myExport.addTitle = String.Format("Name: {0},{1}", lastName, firstName));
클래스:
public class CsvExport
{
List<string> fields = new List<string>();
public string addTitle { get; set; } // string for the first row of the export
List<Dictionary<string, object>> rows = new List<Dictionary<string, object>>();
Dictionary<string, object> currentRow
{
get
{
return rows[rows.Count - 1];
}
}
public object this[string field]
{
set
{
if (!fields.Contains(field)) fields.Add(field);
currentRow[field] = value;
}
}
public void AddRow()
{
rows.Add(new Dictionary<string, object>());
}
string MakeValueCsvFriendly(object value)
{
if (value == null) return "";
if (value is Nullable && ((INullable)value).IsNull) return "";
if (value is DateTime)
{
if (((DateTime)value).TimeOfDay.TotalSeconds == 0)
return ((DateTime)value).ToString("yyyy-MM-dd");
return ((DateTime)value).ToString("yyyy-MM-dd HH:mm:ss");
}
string output = value.ToString();
if (output.Contains(",") || output.Contains("\""))
output = '"' + output.Replace("\"", "\"\"") + '"';
return output;
}
public string Export()
{
StringBuilder sb = new StringBuilder();
// if there is a title
if (!string.IsNullOrEmpty(addTitle))
{
// escape chars that would otherwise break the row / export
char[] csvTokens = new[] { '\"', ',', '\n', '\r' };
if (addTitle.IndexOfAny(csvTokens) >= 0)
{
addTitle = "\"" + addTitle.Replace("\"", "\"\"") + "\"";
}
sb.Append(addTitle).Append(",");
sb.AppendLine();
}
// The header
foreach (string field in fields)
sb.Append(field).Append(",");
sb.AppendLine();
// The rows
foreach (Dictionary<string, object> row in rows)
{
foreach (string field in fields)
sb.Append(MakeValueCsvFriendly(row[field])).Append(",");
sb.AppendLine();
}
return sb.ToString();
}
public void ExportToFile(string path)
{
File.WriteAllText(path, Export());
}
public byte[] ExportToBytes()
{
return Encoding.UTF8.GetBytes(Export());
}
}
nuget을 사용하여 얻을 수 있는 CSV용 오픈 소스 라이브러리가 있습니다.http://joshclose.github.io/CsvHelper/
ExportToStream을 추가하여 csv를 하드 드라이브에 저장할 필요가 없습니다.
public Stream ExportToStream()
{
MemoryStream stream = new MemoryStream();
StreamWriter writer = new StreamWriter(stream);
writer.Write(Export(true));
writer.Flush();
stream.Position = 0;
return stream;
}
추가했습니다.
public void ExportToFile(string path, DataTable tabela)
{
DataColumnCollection colunas = tabela.Columns;
foreach (DataRow linha in tabela.Rows)
{
this.AddRow();
foreach (DataColumn coluna in colunas)
{
this[coluna.ColumnName] = linha[coluna];
}
}
this.ExportToFile(path);
}
이전 코드는 이전 코드에서는 작동하지 않습니다.NET 버전3.5 버전의 프레임워크의 경우 다음 다른 버전을 사용합니다.
public void ExportToFile(string path)
{
bool abort = false;
bool exists = false;
do
{
exists = File.Exists(path);
if (!exists)
{
if( !Convert.ToBoolean( File.CreateText(path) ) )
abort = true;
}
} while (!exists || abort);
if (!abort)
{
//File.OpenWrite(path);
using (StreamWriter w = File.AppendText(path))
{
w.WriteLine("hello");
}
}
//File.WriteAllText(path, Export());
}
정말 고마워요!클래스를 다음과 같이 수정했습니다.
- 코드로 하드코딩되는 대신 변수 딜리미터를 사용한다.
- "newLines(\n \r \n\의 \r \
MakeValueCsvFriendly
코드:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Data.SqlTypes;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
public class CsvExport
{
public char delim = ';';
/// <summary>
/// To keep the ordered list of column names
/// </summary>
List<string> fields = new List<string>();
/// <summary>
/// The list of rows
/// </summary>
List<Dictionary<string, object>> rows = new List<Dictionary<string, object>>();
/// <summary>
/// The current row
/// </summary>
Dictionary<string, object> currentRow { get { return rows[rows.Count - 1]; } }
/// <summary>
/// Set a value on this column
/// </summary>
public object this[string field]
{
set
{
// Keep track of the field names, because the dictionary loses the ordering
if (!fields.Contains(field)) fields.Add(field);
currentRow[field] = value;
}
}
/// <summary>
/// Call this before setting any fields on a row
/// </summary>
public void AddRow()
{
rows.Add(new Dictionary<string, object>());
}
/// <summary>
/// Converts a value to how it should output in a csv file
/// If it has a comma, it needs surrounding with double quotes
/// Eg Sydney, Australia -> "Sydney, Australia"
/// Also if it contains any double quotes ("), then they need to be replaced with quad quotes[sic] ("")
/// Eg "Dangerous Dan" McGrew -> """Dangerous Dan"" McGrew"
/// </summary>
string MakeValueCsvFriendly(object value)
{
if (value == null) return "";
if (value is INullable && ((INullable)value).IsNull) return "";
if (value is DateTime)
{
if (((DateTime)value).TimeOfDay.TotalSeconds == 0)
return ((DateTime)value).ToString("yyyy-MM-dd");
return ((DateTime)value).ToString("yyyy-MM-dd HH:mm:ss");
}
string output = value.ToString();
if (output.Contains(delim) || output.Contains("\""))
output = '"' + output.Replace("\"", "\"\"") + '"';
if (Regex.IsMatch(output, @"(?:\r\n|\n|\r)"))
output = string.Join(" ", Regex.Split(output, @"(?:\r\n|\n|\r)"));
return output;
}
/// <summary>
/// Output all rows as a CSV returning a string
/// </summary>
public string Export()
{
StringBuilder sb = new StringBuilder();
// The header
foreach (string field in fields)
sb.Append(field).Append(delim);
sb.AppendLine();
// The rows
foreach (Dictionary<string, object> row in rows)
{
foreach (string field in fields)
sb.Append(MakeValueCsvFriendly(row[field])).Append(delim);
sb.AppendLine();
}
return sb.ToString();
}
/// <summary>
/// Exports to a file
/// </summary>
public void ExportToFile(string path)
{
File.WriteAllText(path, Export());
}
/// <summary>
/// Exports as raw UTF8 bytes
/// </summary>
public byte[] ExportToBytes()
{
return Encoding.UTF8.GetBytes(Export());
}
}
ADO를 사용하여 이 작업을 수행할 수도 있습니다.http://weblogs.asp.net/fmarguerie/archive/2003/10/01/29964.aspx
원래 클래스에 문제가 있습니다.즉, 새 열을 추가할 경우 내보내기 메서드에서 KeyNotFoundException이 수신됩니다.예를 들어 다음과 같습니다.
static void Main(string[] args)
{
var export = new CsvExport();
export.AddRow();
export["Region"] = "New York, USA";
export["Sales"] = 100000;
export["Date Opened"] = new DateTime(2003, 12, 31);
export.AddRow();
export["Region"] = "Sydney \"in\" Australia";
export["Sales"] = 50000;
export["Date Opened"] = new DateTime(2005, 1, 1, 9, 30, 0);
export["Balance"] = 3.45f; //Exception is throwed for this new column
export.ExportToFile("Somefile.csv");
}
이를 해결하기 위해 @KeyboardCowboy의 리플렉션 사용 아이디어를 사용하여 동일한 컬럼이 없는 행을 추가할 수 있도록 코드를 수정했습니다.익명 클래스의 인스턴스를 사용할 수 있습니다.예를 들어 다음과 같습니다.
static void Main(string[] args)
{
var export = new CsvExporter();
export.AddRow(new {A = 12, B = "Empty"});
export.AddRow(new {A = 34.5f, D = false});
export.ExportToFile("File.csv");
}
여기서 소스 코드를 다운로드할 수 있습니다.자유롭게 사용 및 변경 가능.
쓰는 행이 모두 같은 클래스라면 범용 클래스 CsvWriter.cs을 만들었습니다.이 클래스는 RAM 사용률이 향상되어 대용량 파일 쓰기에 매우 적합합니다.또한 원하는 데이터 유형에 포맷터를 추가할 수 있습니다.사용 예:
class Program
{
static void Main(string[] args)
{
var writer = new CsvWriter<Person>("Persons.csv");
writer.AddFormatter<DateTime>(d => d.ToString("MM/dd/yyyy"));
writer.WriteHeaders();
writer.WriteRows(GetPersons());
writer.Flush();
writer.Close();
}
private static IEnumerable<Person> GetPersons()
{
yield return new Person
{
FirstName = "Jhon",
LastName = "Doe",
Sex = 'M'
};
yield return new Person
{
FirstName = "Jhane",
LastName = "Doe",
Sex = 'F',
BirthDate = DateTime.Now
};
}
}
class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public char Sex { get; set; }
public DateTime BirthDate { get; set; }
}
이 작업을 수행하려면 하나의 기능만 필요합니다.솔루션 탐색기에 폴더를 만들고 csv 파일을 저장한 후 해당 파일을 사용자에게 내보내기만 하면 됩니다.
내 경우 폴더 다운로드가 있습니다.먼저 모든 콘텐츠를 해당 디렉토리로 내보낸 후 사용자에게 내보냅니다.response.end 처리에는 ThreadAbortException을 사용했습니다.그래서 이 기능은 100% 정품이며, 제 솔루션에서 작동합니다.
protected void lnkExport_OnClick(object sender, EventArgs e)
{
string filename = strFileName = "Export.csv";
DataTable dt = obj.GetData();
// call the content and load it into the datatable
strFileName = Server.MapPath("Downloads") + "\\" + strFileName;
// creating a file in the downloads folder in your solution explorer
TextWriter tw = new StreamWriter(strFileName);
// using the built in class textwriter for writing your content in the exporting file
string strData = "Username,Password,City";
// above line is the header for your exported file. So add headings for your coloumns in excel(.csv) file and seperate them with ","
strData += Environment.NewLine;
// setting the environment to the new line
foreach (DataRow dr in dt.Rows)
{
strData += dr["Username"].ToString() + "," + dr["Password"].ToString() + "," + dr["City"].ToString();
strData += Environment.NewLine;
}
// everytime when loop execute, it adds a line into the file
tw.Write(strData);
// writing the contents in file
tw.Close();
// closing the file
Response.Redirect("Downloads/" + filename);
// exporting the file to the user as a popup to save as....
}
언급URL : https://stackoverflow.com/questions/2422212/how-to-create-csv-excel-file-c
'programing' 카테고리의 다른 글
그림자가 퍼지거나 흐릿해지는 것을 제어하는 방법 (0) | 2023.04.24 |
---|---|
system.management를 참조합니다.visual studio의 automation.dll (0) | 2023.04.24 |
HTTP 오류 403.14 - 금지 - 웹 서버가 이 디렉토리의 내용을 나열하지 않도록 구성되어 있습니다. (0) | 2023.04.24 |
ASP.NET Core 1.1은 로컬에서 정상적으로 실행되지만 Azure에 게시할 때 "애플리케이션 시작 중 오류가 발생했습니다."라고 표시됩니다. (0) | 2023.04.24 |
URL에서 더하기(+) 기호를 인코딩하는 방법 (0) | 2023.04.24 |