c#简单实现生成csv文件

最近项目中用到Sql Server的DtS数据导入功能。其中dtsx模板的制作和csv的生成是重中之中。在这方面,自己完全是个菜鸟,尤其是dtsx,那玩意让我栽了很多次,幸亏在同事的热心帮助下最终让我得偿所愿,哈哈,真不容易。好了,闲言少叙,下面就记录下自己实现的一个简单的生成csv文件的方式。代码如下:
ContractedBlock.gif ExpandedBlockStart.gif Code
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 : classnew()
        {
            
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("#.#")的形式)。
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值