c#简单实现生成csv文件
2009-11-26 20:02
597 查看
最近项目中用到Sql Server的DtS数据导入功能。其中dtsx模板的制作和csv的生成是重中之中。在这方面,自己完全是个菜鸟,尤其是dtsx,那玩意让我栽了很多次,幸亏在同事的热心帮助下最终让我得偿所愿,哈哈,真不容易。好了,闲言少叙,下面就记录下自己实现的一个简单的生成csv文件的方式。代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.IO;
namespace DotNet.Common.Util
{
public static class CsvHelper
{
/// <summary>
/// 保存csv文件
/// </summary>
/// <param name="fileName"></param>
/// <param name="content"></param>
public static bool SaveAsCSV<T>(string fileName, IList<T> listModel) where T : class, new()
{
bool flag = false;
try
{
StringBuilder sb = new StringBuilder();
//通过反射 显示要显示的列
BindingFlags bf = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static;//反射标识
Type objType = typeof(T);
PropertyInfo[] propInfoArr = objType.GetProperties(bf);
string header = string.Empty;
List<string> listPropertys = new List<string>();
foreach (PropertyInfo info in propInfoArr)
{
if (string.Compare(info.Name.ToUpper(), "ID") != 0) //不考虑自增长的id或者自动生成的guid等
{
if (!listPropertys.Contains(info.Name))
{
listPropertys.Add(info.Name);
}
header += info.Name + ",";
}
}
sb.AppendLine(header.Trim(',')); //csv头
foreach (T model in listModel)
{
string strModel = string.Empty;
foreach (string strProp in listPropertys)
{
foreach (PropertyInfo propInfo in propInfoArr)
{
if (string.Compare(propInfo.Name.ToUpper(), strProp.ToUpper()) == 0)
{
PropertyInfo modelProperty = model.GetType().GetProperty(propInfo.Name);
if (modelProperty != null)
{
object objResult = modelProperty.GetValue(model, null);
string result = ((objResult == null) ? string.Empty : objResult).ToString().Trim();
if (result.IndexOf(',') != -1)
{
result = "\"" + result.Replace("\"", "\"\"") + "\""; //特殊字符处理 ?
//result = result.Replace("\"", "“").Replace(',', ',') + "\"";
}
if (!string.IsNullOrEmpty(result))
{
Type valueType = modelProperty.PropertyType;
if (valueType.Equals(typeof(Nullable<decimal>)))
{
result = decimal.Parse(result).ToString("#.#");
}
else if (valueType.Equals(typeof(decimal)))
{
result = decimal.Parse(result).ToString("#.#");
}
else if (valueType.Equals(typeof(Nullable<double>)))
{
result = double.Parse(result).ToString("#.#");
}
else if (valueType.Equals(typeof(double)))
{
result = double.Parse(result).ToString("#.#");
}
else if (valueType.Equals(typeof(Nullable<float>)))
{
result = float.Parse(result).ToString("#.#");
}
else if (valueType.Equals(typeof(float)))
{
result = float.Parse(result).ToString("#.#");
}
}
strModel += result + ",";
}
else
{
strModel += ",";
}
break;
}
}
}
strModel = strModel.Substring(0, strModel.Length - 1);
sb.AppendLine(strModel);
}
string content = sb.ToString();
string dir = Directory.GetCurrentDirectory();
string fullName = Path.Combine(dir, fileName);
if (File.Exists(fullName)) File.Delete(fullName);
using (FileStream fs = new FileStream(fullName, FileMode.CreateNew, FileAccess.Write))
{
StreamWriter sw = new StreamWriter(fs, Encoding.Default);
sw.Flush();
sw.Write(content);
sw.Flush();
sw.Close();
}
flag = true;
}
catch
{
flag = false;
}
return flag;
}
}
}
需要说明的是:
1、生成csv的时候,我们没有考虑实体类和数据库字段的顺序,只是通过反射遍历属性而已。如果要更加直观地看到dtsx模板导出列和csv导入列之间的关系,建议实体类和数据库的字段顺序一致。
2、对于海量数据,这个方法的StringBuilder在保存字符串的时候会有明显的性能问题。这个地方还可以改进,改进的方法请关注老赵的这一篇和即将出现的下一篇。
3、这个生成csv文件的方式不是很灵活,您可以改进成自己需要的方式,比如列名,写入列顺序等自己来配置。
ps:有小数点的数值型保留几位小数看实际项目需要,本文统一保存为1位小数(ToString("#.#")的形式)。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.IO;
namespace DotNet.Common.Util
{
public static class CsvHelper
{
/// <summary>
/// 保存csv文件
/// </summary>
/// <param name="fileName"></param>
/// <param name="content"></param>
public static bool SaveAsCSV<T>(string fileName, IList<T> listModel) where T : class, new()
{
bool flag = false;
try
{
StringBuilder sb = new StringBuilder();
//通过反射 显示要显示的列
BindingFlags bf = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static;//反射标识
Type objType = typeof(T);
PropertyInfo[] propInfoArr = objType.GetProperties(bf);
string header = string.Empty;
List<string> listPropertys = new List<string>();
foreach (PropertyInfo info in propInfoArr)
{
if (string.Compare(info.Name.ToUpper(), "ID") != 0) //不考虑自增长的id或者自动生成的guid等
{
if (!listPropertys.Contains(info.Name))
{
listPropertys.Add(info.Name);
}
header += info.Name + ",";
}
}
sb.AppendLine(header.Trim(',')); //csv头
foreach (T model in listModel)
{
string strModel = string.Empty;
foreach (string strProp in listPropertys)
{
foreach (PropertyInfo propInfo in propInfoArr)
{
if (string.Compare(propInfo.Name.ToUpper(), strProp.ToUpper()) == 0)
{
PropertyInfo modelProperty = model.GetType().GetProperty(propInfo.Name);
if (modelProperty != null)
{
object objResult = modelProperty.GetValue(model, null);
string result = ((objResult == null) ? string.Empty : objResult).ToString().Trim();
if (result.IndexOf(',') != -1)
{
result = "\"" + result.Replace("\"", "\"\"") + "\""; //特殊字符处理 ?
//result = result.Replace("\"", "“").Replace(',', ',') + "\"";
}
if (!string.IsNullOrEmpty(result))
{
Type valueType = modelProperty.PropertyType;
if (valueType.Equals(typeof(Nullable<decimal>)))
{
result = decimal.Parse(result).ToString("#.#");
}
else if (valueType.Equals(typeof(decimal)))
{
result = decimal.Parse(result).ToString("#.#");
}
else if (valueType.Equals(typeof(Nullable<double>)))
{
result = double.Parse(result).ToString("#.#");
}
else if (valueType.Equals(typeof(double)))
{
result = double.Parse(result).ToString("#.#");
}
else if (valueType.Equals(typeof(Nullable<float>)))
{
result = float.Parse(result).ToString("#.#");
}
else if (valueType.Equals(typeof(float)))
{
result = float.Parse(result).ToString("#.#");
}
}
strModel += result + ",";
}
else
{
strModel += ",";
}
break;
}
}
}
strModel = strModel.Substring(0, strModel.Length - 1);
sb.AppendLine(strModel);
}
string content = sb.ToString();
string dir = Directory.GetCurrentDirectory();
string fullName = Path.Combine(dir, fileName);
if (File.Exists(fullName)) File.Delete(fullName);
using (FileStream fs = new FileStream(fullName, FileMode.CreateNew, FileAccess.Write))
{
StreamWriter sw = new StreamWriter(fs, Encoding.Default);
sw.Flush();
sw.Write(content);
sw.Flush();
sw.Close();
}
flag = true;
}
catch
{
flag = false;
}
return flag;
}
}
}
需要说明的是:
1、生成csv的时候,我们没有考虑实体类和数据库字段的顺序,只是通过反射遍历属性而已。如果要更加直观地看到dtsx模板导出列和csv导入列之间的关系,建议实体类和数据库的字段顺序一致。
2、对于海量数据,这个方法的StringBuilder在保存字符串的时候会有明显的性能问题。这个地方还可以改进,改进的方法请关注老赵的这一篇和即将出现的下一篇。
3、这个生成csv文件的方式不是很灵活,您可以改进成自己需要的方式,比如列名,写入列顺序等自己来配置。
ps:有小数点的数值型保留几位小数看实际项目需要,本文统一保存为1位小数(ToString("#.#")的形式)。
相关文章推荐
- 简单实现C#生成Excel 2007文件并下载
- 简单实现C#生成Excel 2007文件并下载
- 简单实现C#生成Excel 2007文件并下载
- 一个简单的QQ隐藏图生成算法 通过jQuery和C#分别实现对.NET Core Web Api的访问以及文件上传
- java 解决调用c语言实现简单HelloWorld函数生成.dll动态链接库的32位dll文件无法在64位机上运行
- 利用PHP生成CSV文件简单示例
- Python实现生成简单的Makefile文件代码示例
- php输出csv文件 简单实现
- 简单实现C#生成XML文件代码
- C#实现保存文件时重名自动生成新文件的方法
- php 生成csv文件(file_put_contents实现)
- c# 判断指定文件是否存在的简单实现
- 简单C#生成静态及相关读取模板文件
- 利用PHP生成CSV文件简单示例
- 用C#实现的简单树型图生成算法!
- 基于C#实现简单离线注册码生成与验证
- 【C#工具类】生成CSV文件
- C# 将DataTable导出生成CSV文件串列问题
- PHP简单实现生成txt文件到指定目录的方法
- 本文实现了一个基于servlet技术的简单的csv文件导出的程序实例。