367 lines
11 KiB
C#
367 lines
11 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Data;
|
|
using System.Diagnostics;
|
|
using System.Globalization;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using System.Text;
|
|
using System.Text.RegularExpressions;
|
|
using System.Threading;
|
|
|
|
namespace AibisDream.Utility
|
|
{
|
|
public class CsvUtil
|
|
{
|
|
// 默认编码
|
|
private static readonly Encoding DefaultEncode = Encoding.UTF8;
|
|
|
|
// 默认分隔符
|
|
private const char FieldSeparator = ',';
|
|
|
|
public static List<string[]> Read(string filePath)
|
|
{
|
|
List<string[]> dataList = new List<string[]>();
|
|
StreamReader reader;
|
|
try
|
|
{
|
|
using (reader = new StreamReader(filePath, DefaultEncode))
|
|
{
|
|
while (!reader.EndOfStream)
|
|
{
|
|
string line = reader.ReadLine();
|
|
if (line == null) break;
|
|
string[] data = line.Split(FieldSeparator);
|
|
dataList.Add(data);
|
|
}
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
foreach (Process process in Process.GetProcesses())
|
|
{
|
|
if (process.ProcessName.ToUpper().Equals("EXCEL"))
|
|
process.Kill();
|
|
}
|
|
|
|
GC.Collect();
|
|
Thread.Sleep(50);
|
|
Console.WriteLine(ex.StackTrace);
|
|
using (reader = new StreamReader(filePath, DefaultEncode))
|
|
{
|
|
while (!reader.EndOfStream)
|
|
{
|
|
string line = reader.ReadLine();
|
|
if (line == null) break;
|
|
string[] data = line.Split(FieldSeparator);
|
|
dataList.Add(data);
|
|
}
|
|
}
|
|
}
|
|
|
|
reader.Close();
|
|
return dataList;
|
|
}
|
|
|
|
public static void WriteCsv(string filePath, List<string[]> dataList)
|
|
{
|
|
StreamWriter writer = new StreamWriter(filePath, false, DefaultEncode);
|
|
foreach (string[] data in dataList)
|
|
{
|
|
writer.WriteLine(string.Join(FieldSeparator, data));
|
|
}
|
|
|
|
writer.Close();
|
|
}
|
|
|
|
public static List<T> ReadAsBean<T>(string filePath) where T : class
|
|
{
|
|
// 反射部分
|
|
var targetType = typeof(T);
|
|
var props = targetType.GetProperties();
|
|
|
|
// 读取CSV
|
|
using var reader = new StreamReader(filePath, DefaultEncode);
|
|
|
|
// 第一行是注释
|
|
reader.ReadLine();
|
|
// 第二行作为title
|
|
var titles = reader.ReadLine()?.Split(FieldSeparator);
|
|
if (titles == null)
|
|
{
|
|
Debug.WriteLine("csv无标题");
|
|
throw new Exception("csv无标题");
|
|
}
|
|
|
|
var res = new List<T>();
|
|
// 第二行开始读配置内容
|
|
while (!reader.EndOfStream)
|
|
{
|
|
string newLine = reader.ReadLine();
|
|
if (string.IsNullOrEmpty(newLine)) break;
|
|
|
|
string[] rowData = newLine.Split(FieldSeparator);
|
|
if (rowData == null || rowData.Length == 0) continue;
|
|
|
|
// 转为Bean
|
|
var obj = Activator.CreateInstance(targetType);
|
|
foreach (var prop in props)
|
|
{
|
|
string name = prop.Name;
|
|
if (!titles.Contains(prop.Name))
|
|
continue;
|
|
|
|
int idx = Array.IndexOf(titles, prop.Name);
|
|
prop.SetValue(obj, GetDefaultValue(prop, rowData[idx]));
|
|
}
|
|
|
|
res.Add(obj as T);
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
public static bool ReadAsDataTable(ref DataTable myCsvDt, string filepath)
|
|
{
|
|
var strPath = filepath; //csv文件的路径
|
|
|
|
try
|
|
{
|
|
bool blnFlag = true;
|
|
|
|
StreamReader reader = new StreamReader(strPath, DefaultEncode);
|
|
myCsvDt = new DataTable();
|
|
while (reader.ReadLine() is { } strLine)
|
|
{
|
|
var aryLine = strLine.Split(FieldSeparator);
|
|
//第一行是列的名字,给datatable加上列名,
|
|
if (blnFlag)
|
|
{
|
|
blnFlag = false;
|
|
var intColCount = aryLine.Length;
|
|
|
|
#region 序号作为列头
|
|
|
|
//int col = 0;
|
|
//for (int i = 0; i < intColCount; i++)
|
|
//{
|
|
// col = i + 1;
|
|
// mydc = new DataColumn(col.ToString());
|
|
// mycsvdt.Columns.Add(mydc);
|
|
//}
|
|
|
|
#endregion
|
|
|
|
#region 第一行作为列头
|
|
|
|
for (int i = 0; i < intColCount; i++)
|
|
{
|
|
myCsvDt.Columns.Add(new DataColumn(aryLine[i]));
|
|
}
|
|
|
|
continue;
|
|
|
|
#endregion
|
|
}
|
|
|
|
//填充数据并加入到datatable中
|
|
myCsvDt.Rows.Add(aryLine);
|
|
}
|
|
|
|
reader.Close();
|
|
return true;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public static void ExportAsCsv(DataTable dt, string savaPath, string strName)
|
|
{
|
|
string strPath = savaPath + "\\" + strName; //保存到指定目录下
|
|
|
|
if (File.Exists(strPath))
|
|
{
|
|
File.Delete(strPath);
|
|
}
|
|
|
|
//先打印标头
|
|
StringBuilder strColu = new StringBuilder();
|
|
StringBuilder strValue = new StringBuilder();
|
|
StreamWriter sw = new StreamWriter(new FileStream(strPath, FileMode.CreateNew), DefaultEncode);
|
|
try
|
|
{
|
|
for (var i = 0; i <= dt.Columns.Count - 1; i++)
|
|
{
|
|
strColu.Append(dt.Columns[i].ColumnName);
|
|
strColu.Append(FieldSeparator);
|
|
}
|
|
|
|
strColu.Remove(strColu.Length - 1, 1); //移出掉最后一个,字符
|
|
sw.WriteLine(strColu);
|
|
foreach (DataRow dr in dt.Rows)
|
|
{
|
|
strValue.Remove(0, strValue.Length); //移出
|
|
for (var i = 0; i <= dt.Columns.Count - 1; i++)
|
|
{
|
|
strValue.Append(dr[i]);
|
|
strValue.Append(FieldSeparator);
|
|
}
|
|
|
|
strValue.Remove(strValue.Length - 1, 1); //移出掉最后一个,字符
|
|
sw.WriteLine(strValue);
|
|
}
|
|
|
|
sw.Close();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Debug.WriteLine(ex.Message);
|
|
sw.Close();
|
|
}
|
|
}
|
|
|
|
#region 类型转换
|
|
|
|
private static object GetDefaultValue(PropertyInfo prop, string value)
|
|
{
|
|
return prop.PropertyType.Name switch
|
|
{
|
|
"String" => ToNormalString(value),
|
|
"Int32" => ToInt32(value),
|
|
"Decimal" => ToDecimal(value),
|
|
"Single" => ToFloat(value),
|
|
"Boolean" => ToBoolean(value),
|
|
"DateTime" => ToDateTime(value),
|
|
"Double" => ToDouble(value),
|
|
_ => ToEnum(value, prop)
|
|
};
|
|
}
|
|
|
|
private static object ToEnum(string value, PropertyInfo prop)
|
|
{
|
|
return prop.PropertyType.BaseType == typeof(Enum) ? Enum.Parse(prop.PropertyType, value) : null;
|
|
}
|
|
|
|
///<summary>
|
|
/// 转换为Int32
|
|
/// </summary>
|
|
private static int ToInt32(string obj)
|
|
{
|
|
if (string.IsNullOrEmpty(obj)) return 0;
|
|
try
|
|
{
|
|
if (obj.Contains("."))
|
|
return (int)Convert.ToSingle(obj);
|
|
if (int.TryParse(obj, out var tmp))
|
|
return tmp;
|
|
}
|
|
catch
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// 转换为字符串
|
|
/// </summary>
|
|
private static string ToNormalString(string obj)
|
|
{
|
|
if (obj == null)
|
|
return string.Empty;
|
|
try
|
|
{
|
|
return Convert.ToString(obj);
|
|
}
|
|
catch
|
|
{
|
|
return string.Empty;
|
|
}
|
|
}
|
|
|
|
///<summary>
|
|
/// 转换为日期
|
|
/// </summary>
|
|
private static DateTime ToDateTime(string obj)
|
|
{
|
|
if (string.IsNullOrEmpty(obj))
|
|
{
|
|
return Convert.ToDateTime("1970-01-01 00:00:00");
|
|
}
|
|
|
|
try
|
|
{
|
|
return Convert.ToDateTime(obj);
|
|
}
|
|
catch
|
|
{
|
|
return Convert.ToDateTime("1970-01-01 00:00:00");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 转换为布尔型
|
|
/// </summary>
|
|
private static bool ToBoolean(string obj)
|
|
{
|
|
if (obj == null) return false;
|
|
|
|
return obj.ToLower() == "true" || obj == "1";
|
|
}
|
|
|
|
/// <summary>
|
|
/// 转换为十进制数值
|
|
/// </summary>
|
|
private static Decimal ToDecimal(string obj)
|
|
{
|
|
if (obj == null)
|
|
{
|
|
return 0M;
|
|
}
|
|
|
|
var resultString = Regex.Replace(obj, "[^0-9.]", "");
|
|
var result = resultString.Length == 0 ? 0M : decimal.Parse(resultString, CultureInfo.CurrentCulture);
|
|
if (obj.StartsWith("-"))
|
|
{
|
|
result *= -1M;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
///<summary>
|
|
/// 转换为双精度.
|
|
/// </summary>
|
|
private static double ToDouble(string obj)
|
|
{
|
|
if (double.TryParse(obj, out var num))
|
|
return num;
|
|
else
|
|
return 0;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 转换为单精度.
|
|
/// </summary>
|
|
private static float ToFloat(string value)
|
|
{
|
|
var normalStr = ToNormalString(value);
|
|
if (string.IsNullOrEmpty(normalStr))
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
if (float.TryParse(value, NumberStyles.Float, CultureInfo.InvariantCulture, out var result))
|
|
return result;
|
|
else
|
|
return 0;
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
} |