ExcelHelper.cs 67 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572
  1. using NPOI.HSSF.UserModel;
  2. using NPOI.SS.UserModel;
  3. using NPOI.SS.Util;
  4. using NPOI.XSSF.UserModel;
  5. using System;
  6. using System.Collections;
  7. using System.Collections.Generic;
  8. using System.Data;
  9. using System.Data.OleDb;
  10. using System.IO;
  11. using System.Linq;
  12. using System.Reflection;
  13. using System.Text;
  14. using System.Text.RegularExpressions;
  15. using System.Threading.Tasks;
  16. namespace SysBaseLibs
  17. {
  18. public class ExcelHelper
  19. {
  20. /// <summary>
  21. /// 将数据导出至Excel文件
  22. /// </summary>
  23. /// <param name="Table">DataTable对象</param>
  24. /// <param name="ExcelFilePath">Excel文件路径</param>
  25. public static bool OutputToExcel(DataTable Table, string ExcelFilePath)
  26. {
  27. if (File.Exists(ExcelFilePath))
  28. {
  29. throw new Exception("该文件已经存在!");
  30. }
  31. if ((Table.TableName.Trim().Length == 0) || (Table.TableName.ToLower() == "table"))
  32. {
  33. Table.TableName = "Sheet1";
  34. }
  35. //数据表的列数
  36. int ColCount = Table.Columns.Count;
  37. //用于记数,实例化参数时的序号
  38. int i = 0;
  39. //创建参数
  40. OleDbParameter[] para = new OleDbParameter[ColCount];
  41. //创建表结构的SQL语句
  42. string TableStructStr = @"Create Table " + Table.TableName + "(";
  43. //连接字符串
  44. string connString = @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + ExcelFilePath + ";Extended Properties=Excel 8.0;";
  45. OleDbConnection objConn = new OleDbConnection(connString);
  46. //创建表结构
  47. OleDbCommand objCmd = new OleDbCommand();
  48. //数据类型集合
  49. ArrayList DataTypeList = new ArrayList();
  50. DataTypeList.Add("System.Decimal");
  51. DataTypeList.Add("System.Double");
  52. DataTypeList.Add("System.Int16");
  53. DataTypeList.Add("System.Int32");
  54. DataTypeList.Add("System.Int64");
  55. DataTypeList.Add("System.Single");
  56. //遍历数据表的所有列,用于创建表结构
  57. foreach (DataColumn col in Table.Columns)
  58. {
  59. //如果列属于数字列,则设置该列的数据类型为double
  60. if (DataTypeList.IndexOf(col.DataType.ToString()) >= 0)
  61. {
  62. para[i] = new OleDbParameter("@" + col.ColumnName, OleDbType.Double);
  63. objCmd.Parameters.Add(para[i]);
  64. //如果是最后一列
  65. if (i + 1 == ColCount)
  66. {
  67. TableStructStr += col.ColumnName + " double)";
  68. }
  69. else
  70. {
  71. TableStructStr += col.ColumnName + " double,";
  72. }
  73. }
  74. else
  75. {
  76. para[i] = new OleDbParameter("@" + col.ColumnName, OleDbType.VarChar);
  77. objCmd.Parameters.Add(para[i]);
  78. //如果是最后一列
  79. if (i + 1 == ColCount)
  80. {
  81. TableStructStr += col.ColumnName + " varchar)";
  82. }
  83. else
  84. {
  85. TableStructStr += col.ColumnName + " varchar,";
  86. }
  87. }
  88. i++;
  89. }
  90. //创建Excel文件及文件结构
  91. try
  92. {
  93. objCmd.Connection = objConn;
  94. objCmd.CommandText = TableStructStr;
  95. if (objConn.State == ConnectionState.Closed)
  96. {
  97. objConn.Open();
  98. }
  99. objCmd.ExecuteNonQuery();
  100. }
  101. catch (Exception exp)
  102. {
  103. throw exp;
  104. }
  105. //插入记录的SQL语句
  106. string InsertSql_1 = "Insert into " + Table.TableName + " (";
  107. string InsertSql_2 = " Values (";
  108. string InsertSql = "";
  109. //遍历所有列,用于插入记录,在此创建插入记录的SQL语句
  110. for (int colID = 0; colID < ColCount; colID++)
  111. {
  112. if (colID + 1 == ColCount) //最后一列
  113. {
  114. InsertSql_1 += Table.Columns[colID].ColumnName + ")";
  115. InsertSql_2 += "@" + Table.Columns[colID].ColumnName + ")";
  116. }
  117. else
  118. {
  119. InsertSql_1 += Table.Columns[colID].ColumnName + ",";
  120. InsertSql_2 += "@" + Table.Columns[colID].ColumnName + ",";
  121. }
  122. }
  123. InsertSql = InsertSql_1 + InsertSql_2;
  124. //遍历数据表的所有数据行
  125. for (int rowID = 0; rowID < Table.Rows.Count; rowID++)
  126. {
  127. for (int colID = 0; colID < ColCount; colID++)
  128. {
  129. if (para[colID].DbType == DbType.Double && Table.Rows[rowID][colID].ToString().Trim() == "")
  130. {
  131. para[colID].Value = 0;
  132. }
  133. else
  134. {
  135. para[colID].Value = Table.Rows[rowID][colID].ToString().Trim();
  136. }
  137. }
  138. try
  139. {
  140. objCmd.CommandText = InsertSql;
  141. objCmd.ExecuteNonQuery();
  142. }
  143. catch (Exception exp)
  144. {
  145. string str = exp.Message;
  146. }
  147. }
  148. try
  149. {
  150. if (objConn.State == ConnectionState.Open)
  151. {
  152. objConn.Close();
  153. }
  154. }
  155. catch (Exception exp)
  156. {
  157. throw exp;
  158. }
  159. return true;
  160. }
  161. /// <summary>
  162. /// 将数据导出至Excel文件
  163. /// </summary>
  164. /// <param name="Table">DataTable对象</param>
  165. /// <param name="Columns">要导出的数据列集合</param>
  166. /// <param name="ExcelFilePath">Excel文件路径</param>
  167. public static bool OutputToExcel(DataTable Table, ArrayList Columns, string ExcelFilePath)
  168. {
  169. if (File.Exists(ExcelFilePath))
  170. {
  171. throw new Exception("该文件已经存在!");
  172. }
  173. //如果数据列数大于表的列数,取数据表的所有列
  174. if (Columns.Count > Table.Columns.Count)
  175. {
  176. for (int s = Table.Columns.Count + 1; s <= Columns.Count; s++)
  177. {
  178. Columns.RemoveAt(s); //移除数据表列数后的所有列
  179. }
  180. }
  181. //遍历所有的数据列,如果有数据列的数据类型不是 DataColumn,则将它移除
  182. DataColumn column = new DataColumn();
  183. for (int j = 0; j < Columns.Count; j++)
  184. {
  185. try
  186. {
  187. column = (DataColumn)Columns[j];
  188. }
  189. catch (Exception)
  190. {
  191. Columns.RemoveAt(j);
  192. }
  193. }
  194. if ((Table.TableName.Trim().Length == 0) || (Table.TableName.ToLower() == "table"))
  195. {
  196. Table.TableName = "Sheet1";
  197. }
  198. //数据表的列数
  199. int ColCount = Columns.Count;
  200. //创建参数
  201. OleDbParameter[] para = new OleDbParameter[ColCount];
  202. //创建表结构的SQL语句
  203. string TableStructStr = @"Create Table " + Table.TableName + "(";
  204. //连接字符串
  205. string connString = @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + ExcelFilePath + ";Extended Properties=Excel 8.0;";
  206. OleDbConnection objConn = new OleDbConnection(connString);
  207. //创建表结构
  208. OleDbCommand objCmd = new OleDbCommand();
  209. //数据类型集合
  210. ArrayList DataTypeList = new ArrayList();
  211. DataTypeList.Add("System.Decimal");
  212. DataTypeList.Add("System.Double");
  213. DataTypeList.Add("System.Int16");
  214. DataTypeList.Add("System.Int32");
  215. DataTypeList.Add("System.Int64");
  216. DataTypeList.Add("System.Single");
  217. DataColumn col = new DataColumn();
  218. //遍历数据表的所有列,用于创建表结构
  219. for (int k = 0; k < ColCount; k++)
  220. {
  221. col = (DataColumn)Columns[k];
  222. //列的数据类型是数字型
  223. if (DataTypeList.IndexOf(col.DataType.ToString().Trim()) >= 0)
  224. {
  225. para[k] = new OleDbParameter("@" + col.Caption.Trim(), OleDbType.Double);
  226. objCmd.Parameters.Add(para[k]);
  227. //如果是最后一列
  228. if (k + 1 == ColCount)
  229. {
  230. TableStructStr += col.Caption.Trim() + " Double)";
  231. }
  232. else
  233. {
  234. TableStructStr += col.Caption.Trim() + " Double,";
  235. }
  236. }
  237. else
  238. {
  239. para[k] = new OleDbParameter("@" + col.Caption.Trim(), OleDbType.VarChar);
  240. objCmd.Parameters.Add(para[k]);
  241. //如果是最后一列
  242. if (k + 1 == ColCount)
  243. {
  244. TableStructStr += col.Caption.Trim() + " VarChar)";
  245. }
  246. else
  247. {
  248. TableStructStr += col.Caption.Trim() + " VarChar,";
  249. }
  250. }
  251. }
  252. //创建Excel文件及文件结构
  253. try
  254. {
  255. objCmd.Connection = objConn;
  256. objCmd.CommandText = TableStructStr;
  257. if (objConn.State == ConnectionState.Closed)
  258. {
  259. objConn.Open();
  260. }
  261. objCmd.ExecuteNonQuery();
  262. }
  263. catch (Exception exp)
  264. {
  265. throw exp;
  266. }
  267. //插入记录的SQL语句
  268. string InsertSql_1 = "Insert into " + Table.TableName + " (";
  269. string InsertSql_2 = " Values (";
  270. string InsertSql = "";
  271. //遍历所有列,用于插入记录,在此创建插入记录的SQL语句
  272. for (int colID = 0; colID < ColCount; colID++)
  273. {
  274. if (colID + 1 == ColCount) //最后一列
  275. {
  276. InsertSql_1 += Columns[colID].ToString().Trim() + ")";
  277. InsertSql_2 += "@" + Columns[colID].ToString().Trim() + ")";
  278. }
  279. else
  280. {
  281. InsertSql_1 += Columns[colID].ToString().Trim() + ",";
  282. InsertSql_2 += "@" + Columns[colID].ToString().Trim() + ",";
  283. }
  284. }
  285. InsertSql = InsertSql_1 + InsertSql_2;
  286. //遍历数据表的所有数据行
  287. DataColumn DataCol = new DataColumn();
  288. for (int rowID = 0; rowID < Table.Rows.Count; rowID++)
  289. {
  290. for (int colID = 0; colID < ColCount; colID++)
  291. {
  292. //因为列不连续,所以在取得单元格时不能用行列编号,列需得用列的名称
  293. DataCol = (DataColumn)Columns[colID];
  294. if (para[colID].DbType == DbType.Double && Table.Rows[rowID][DataCol.Caption].ToString().Trim() == "")
  295. {
  296. para[colID].Value = 0;
  297. }
  298. else
  299. {
  300. para[colID].Value = Table.Rows[rowID][DataCol.Caption].ToString().Trim();
  301. }
  302. }
  303. try
  304. {
  305. objCmd.CommandText = InsertSql;
  306. objCmd.ExecuteNonQuery();
  307. }
  308. catch (Exception exp)
  309. {
  310. string str = exp.Message;
  311. }
  312. }
  313. try
  314. {
  315. if (objConn.State == ConnectionState.Open)
  316. {
  317. objConn.Close();
  318. }
  319. }
  320. catch (Exception exp)
  321. {
  322. throw exp;
  323. }
  324. return true;
  325. }
  326. /// <summary>
  327. /// 获取Excel文件数据表列表
  328. /// </summary>
  329. public static ArrayList GetExcelTables(string ExcelFileName)
  330. {
  331. DataTable dt = new DataTable();
  332. ArrayList TablesList = new ArrayList();
  333. if (File.Exists(ExcelFileName))
  334. {
  335. using (OleDbConnection conn = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Extended Properties=Excel 8.0;Data Source=" + ExcelFileName))
  336. {
  337. try
  338. {
  339. conn.Open();
  340. dt = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, new object[] { null, null, null, "TABLE" });
  341. }
  342. catch (Exception exp)
  343. {
  344. throw exp;
  345. }
  346. //获取数据表个数
  347. int tablecount = dt.Rows.Count;
  348. for (int i = 0; i < tablecount; i++)
  349. {
  350. string tablename = dt.Rows[i][2].ToString().Trim().TrimEnd('$');
  351. if (TablesList.IndexOf(tablename) < 0)
  352. {
  353. TablesList.Add(tablename);
  354. }
  355. }
  356. }
  357. }
  358. return TablesList;
  359. }
  360. /// <summary>
  361. /// 将Excel文件导出至DataTable(第一行作为表头)
  362. /// </summary>
  363. /// <param name="ExcelFilePath">Excel文件路径</param>
  364. /// <param name="TableName">数据表名,如果数据表名错误,默认为第一个数据表名</param>
  365. public static DataTable InputFromExcel(string ExcelFilePath, string TableName)
  366. {
  367. if (!File.Exists(ExcelFilePath))
  368. {
  369. throw new Exception("Excel文件不存在!");
  370. }
  371. //如果数据表名不存在,则数据表名为Excel文件的第一个数据表
  372. ArrayList TableList = new ArrayList();
  373. TableList = GetExcelTables(ExcelFilePath);
  374. if (TableName.IndexOf(TableName) < 0)
  375. {
  376. TableName = TableList[0].ToString().Trim();
  377. }
  378. DataTable table = new DataTable();
  379. OleDbConnection dbcon = new OleDbConnection(@"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + ExcelFilePath + ";Extended Properties=Excel 8.0");
  380. OleDbCommand cmd = new OleDbCommand("select * from [" + TableName + "$]", dbcon);
  381. OleDbDataAdapter adapter = new OleDbDataAdapter(cmd);
  382. try
  383. {
  384. if (dbcon.State == ConnectionState.Closed)
  385. {
  386. dbcon.Open();
  387. }
  388. adapter.Fill(table);
  389. }
  390. catch (Exception exp)
  391. {
  392. throw exp;
  393. }
  394. finally
  395. {
  396. if (dbcon.State == ConnectionState.Open)
  397. {
  398. dbcon.Close();
  399. }
  400. }
  401. return table;
  402. }
  403. /// <summary>
  404. /// 获取Excel文件指定数据表的数据列表
  405. /// </summary>
  406. /// <param name="ExcelFileName">Excel文件名</param>
  407. /// <param name="TableName">数据表名</param>
  408. public static ArrayList GetExcelTableColumns(string ExcelFileName, string TableName)
  409. {
  410. DataTable dt = new DataTable();
  411. ArrayList ColsList = new ArrayList();
  412. if (File.Exists(ExcelFileName))
  413. {
  414. using (OleDbConnection conn = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Extended Properties=Excel 8.0;Data Source=" + ExcelFileName))
  415. {
  416. conn.Open();
  417. dt = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Columns, new object[] { null, null, TableName, null });
  418. //获取列个数
  419. int colcount = dt.Rows.Count;
  420. for (int i = 0; i < colcount; i++)
  421. {
  422. string colname = dt.Rows[i]["Column_Name"].ToString().Trim();
  423. ColsList.Add(colname);
  424. }
  425. }
  426. }
  427. return ColsList;
  428. }
  429. public static bool dataTableToCsv(DataTable table, string file)
  430. {
  431. bool lcRetval = false;
  432. if (File.Exists(file))
  433. {
  434. throw new Exception("该文件已经存在!");
  435. }
  436. try
  437. {
  438. string title = "";
  439. FileStream fs = new FileStream(file, FileMode.OpenOrCreate);
  440. //FileStream fs1 = File.Open(file, FileMode.Open, FileAccess.Read);
  441. StreamWriter sw = new StreamWriter(new BufferedStream(fs), System.Text.Encoding.Default);
  442. for (int i = 0; i < table.Columns.Count; i++)
  443. {
  444. title += table.Columns[i].ColumnName + "\t"; //栏位:自动跳到下一单元格
  445. }
  446. title = title.Substring(0, title.Length - 1) + "\n";
  447. sw.Write(title);
  448. foreach (DataRow row in table.Rows)
  449. {
  450. string line = "";
  451. for (int i = 0; i < table.Columns.Count; i++)
  452. {
  453. line += row[i].ToString().Trim() + "\t"; //内容:自动跳到下一单元格
  454. }
  455. line = line.Substring(0, line.Length - 1) + "\n";
  456. sw.Write(line);
  457. }
  458. sw.Close();
  459. fs.Close();
  460. lcRetval = true;
  461. }catch(Exception err)
  462. {
  463. ThreadLog.LogException(err);
  464. }
  465. return lcRetval;
  466. }
  467. }
  468. public static class ExcelHelper2
  469. {
  470. #region Excel导入
  471. /// <summary>
  472. /// 从Excel取数据并记录到List集合里
  473. /// </summary>
  474. /// <param name="cellHeader">单元头的值和名称:{ { "UserName", "姓名" }, { "Age", "年龄" } };</param>
  475. /// <param name="filePath">保存文件绝对路径</param>
  476. /// <param name="errMsg">错误信息</param>
  477. /// <param name="startIndex">数据行开始序列,默认为1(即第二列,从0开始)</param>
  478. /// <returns>转换后的List对象集合</returns>
  479. public static List<T> ExcelToEntityList<T>(this Dictionary<string, string> cellHeader, string filePath, out string errMsg, int startIndex = 1) where T : new()
  480. {
  481. List<T> enlist = new List<T>();
  482. var errorMsg = new StringBuilder();
  483. try
  484. {
  485. if (Regex.IsMatch(filePath, ".xls$")) // 2003
  486. {
  487. enlist = Excel2003ToEntityList<T>(cellHeader, filePath, out errorMsg, startIndex);
  488. }
  489. else if (Regex.IsMatch(filePath, ".xlsx$")) // 2007
  490. {
  491. enlist = Excel2007ToEntityList<T>(cellHeader, filePath, out errorMsg, startIndex);
  492. }
  493. }
  494. catch (Exception ex)
  495. {
  496. errMsg = ex.Message;
  497. //typeof(ExcelHelper).LogError(ex);
  498. return default(List<T>);
  499. }
  500. errMsg = errorMsg.ToString();
  501. return enlist;
  502. }
  503. /// <summary>
  504. /// 从Excel2003取数据并记录到List集合里
  505. /// </summary>
  506. /// <param name="cellHeader">单元头的Key和Value:{ { "UserName", "姓名" }, { "Age", "年龄" } };</param>
  507. /// <param name="filePath">保存文件绝对路径</param>
  508. /// <param name="errorMsg">错误信息</param>
  509. /// <param name="startIndex"></param>
  510. /// <returns>转换好的List对象集合</returns>
  511. private static List<T> Excel2003ToEntityList<T>(this Dictionary<string, string> cellHeader, string filePath, out StringBuilder errorMsg, int startIndex = 1) where T : new()
  512. {
  513. errorMsg = new StringBuilder(); // 错误信息,Excel转换到实体对象时,会有格式的错误信息
  514. List<T> enlist = new List<T>(); // 转换后的集合
  515. try
  516. {
  517. using (FileStream fs = File.OpenRead(filePath))
  518. {
  519. HSSFWorkbook workbook = new HSSFWorkbook(fs);
  520. HSSFSheet sheet = (HSSFSheet)workbook.GetSheetAt(0); // 获取此文件第一个Sheet页
  521. for (int rowIndex = startIndex; rowIndex <= sheet.LastRowNum; rowIndex++)
  522. {
  523. // 1.判断当前行是否空行,若空行就不在进行读取下一行操作,结束Excel读取操作
  524. IRow row = sheet.GetRow(rowIndex);
  525. if (row == null)
  526. {
  527. break;
  528. }
  529. // 2.每一个Excel row转换为一个实体对象
  530. T en = new T();
  531. ExcelRowToEntity(cellHeader, row, rowIndex, en, ref errorMsg);
  532. enlist.Add(en);
  533. }
  534. }
  535. return enlist;
  536. }
  537. catch (Exception ex)
  538. {
  539. //typeof(ExcelHelper).LogError(ex);
  540. return default(List<T>);
  541. }
  542. }
  543. /// <summary>
  544. /// 从Excel2007取数据并记录到List集合里
  545. /// </summary>
  546. /// <param name="cellHeader">单元头的Key和Value:{ { "UserName", "姓名" }, { "Age", "年龄" } };</param>
  547. /// <param name="filePath">保存文件绝对路径</param>
  548. /// <param name="errorMsg">错误信息</param>
  549. /// <param name="startIndex">数据行开始序列,默认为1(即第二列,从0开始)</param>
  550. /// <returns>转换好的List对象集合</returns>
  551. private static List<T> Excel2007ToEntityList<T>(this Dictionary<string, string> cellHeader, string filePath, out StringBuilder errorMsg, int startIndex = 1)
  552. where T : new()
  553. {
  554. errorMsg = new StringBuilder(); // 错误信息,Excel转换到实体对象时,会有格式的错误信息
  555. List<T> enlist = new List<T>(); // 转换后的集合
  556. try
  557. {
  558. using (FileStream fs = File.OpenRead(filePath))
  559. {
  560. XSSFWorkbook workbook = new XSSFWorkbook(fs);
  561. XSSFSheet sheet = (XSSFSheet)workbook.GetSheetAt(0); // 获取此文件第一个Sheet页
  562. for (int rowIndex = startIndex; rowIndex <= sheet.LastRowNum; rowIndex++)
  563. {
  564. // 1.判断当前行是否空行,若空行就不在进行读取下一行操作,结束Excel读取操作
  565. IRow row = sheet.GetRow(rowIndex);
  566. if (row == null)
  567. {
  568. break;
  569. }
  570. // 2.每一个Excel row转换为一个实体对象
  571. T en = new T();
  572. ExcelRowToEntity(cellHeader, row, rowIndex, en, ref errorMsg);
  573. enlist.Add(en);
  574. }
  575. }
  576. return enlist;
  577. }
  578. catch (Exception ex)
  579. {
  580. //typeof(ExcelHelper).LogError(ex);
  581. return default(List<T>);
  582. }
  583. }
  584. #endregion Excel导入
  585. #region Excel导出
  586. /// <summary>
  587. /// 实体类集合导出到EXCEL2003
  588. /// </summary>
  589. /// <param name="cellHeader">单元头的Key和Value:{ { "UserName", "姓名" }, { "Age", "年龄" } };</param>
  590. /// <param name="enList">数据源</param>
  591. /// <param name="sheetName">工作表名称</param>
  592. /// <param name="filePath">文件的下载地址</param>
  593. /// <returns></returns>
  594. public static string EntityListToExcel2003(this Dictionary<string, string> cellHeader, IList enList, string sheetName, string filePath)
  595. {
  596. var lcRetVal = "error@";
  597. try
  598. {
  599. string fileName = $"D-{sheetName}-{DateTime.Now:yyyyMMddHHmmssfff}.xls"; // 文件名称
  600. filePath = filePath.StartsWith("/") ? filePath : ("/" + filePath);
  601. filePath = filePath.EndsWith("/") ? filePath : (filePath + "/");
  602. string path = $"{AppDomain.CurrentDomain.BaseDirectory}{filePath}";
  603. if (!Directory.Exists(path))
  604. Directory.CreateDirectory(path);
  605. // 2.解析单元格头部,设置单元头的中文名称
  606. HSSFWorkbook workbook = new HSSFWorkbook(); // 工作簿
  607. ISheet sheet = workbook.CreateSheet(sheetName); // 工作表
  608. IRow row = sheet.CreateRow(0);
  609. List<string> keys = cellHeader.Keys.ToList();
  610. for (int i = 0; i < keys.Count; i++)
  611. {
  612. row.CreateCell(i).SetCellValue(cellHeader[keys[i]]); // 列名为Key的值
  613. }
  614. // 3.List对象的值赋值到Excel的单元格里
  615. int rowIndex = 1; // 从第二行开始赋值(第一行已设置为单元头)
  616. object propertyValue = null;
  617. foreach (var en in enList)
  618. {
  619. IRow rowTmp = sheet.CreateRow(rowIndex);
  620. for (int i = 0; i < keys.Count; i++) // 根据指定的属性名称,获取对象指定属性的值
  621. {
  622. string cellValue = "";
  623. PropertyInfo propertyInfo = null; // 属性的信息
  624. // 3.1 若属性头的名称包含'.',就表示是子类里的属性,那么就要遍历子类,eg:UserEn.UserName
  625. string[] propertyArray = keys[i].Split(new[] { "." }, StringSplitOptions.RemoveEmptyEntries);
  626. if (keys[i].IndexOf(".", StringComparison.Ordinal) >= 0)
  627. {
  628. // 3.1.1 解析子类属性(这里只解析1层子类,多层子类未处理)
  629. string subClassName = propertyArray[0]; // '.'前面的为子类的名称
  630. string subClassPropertyName = propertyArray[1]; // '.'后面的为子类的属性名称
  631. PropertyInfo subClassInfo = en.GetType().GetProperty(subClassName); // 获取子类的类型
  632. if (subClassInfo != null)
  633. {
  634. // 3.1.2 获取子类的实例
  635. var subClassEn = en.GetType().GetProperty(subClassName)?.GetValue(en, null);
  636. // 3.1.3 根据属性名称获取子类里的属性类型
  637. propertyInfo = subClassInfo.PropertyType.GetProperty(subClassPropertyName);
  638. if (propertyInfo != null)
  639. {
  640. propertyValue = propertyInfo.GetValue(subClassEn, null); // 获取子类属性的值
  641. }
  642. }
  643. }
  644. else
  645. {
  646. // 3.2 若不是子类的属性,直接根据属性名称获取对象对应的属性
  647. propertyInfo = en.GetType().GetProperty(keys[i]);
  648. if (propertyInfo != null)
  649. {
  650. propertyValue = propertyInfo.GetValue(en, null);
  651. }
  652. }
  653. // 3.3 属性值经过转换赋值给单元格值
  654. if (propertyValue != null)
  655. {
  656. if (propertyInfo?.PropertyType.Name == "int" || propertyInfo?.PropertyType.Name == "float" || propertyInfo?.PropertyType.Name == "double" || propertyInfo?.PropertyType.Name == "decimal")
  657. {
  658. var value = Convert.ToDouble(propertyValue);
  659. rowTmp.CreateCell(i).SetCellValue(value);
  660. }
  661. else if (propertyInfo?.PropertyType.Name == "bool")
  662. {
  663. var value = Convert.ToBoolean(propertyValue);
  664. rowTmp.CreateCell(i).SetCellValue(value);
  665. }
  666. else
  667. {
  668. cellValue = propertyValue.ToString();
  669. // 3.3.1 对时间初始值赋值为空
  670. if (cellValue.Trim() == "0001/1/1 0:00:00" || cellValue.Trim() == "0001/1/1 23:59:59")
  671. {
  672. cellValue = "";
  673. }
  674. // 3.4 填充到Excel的单元格里
  675. rowTmp.CreateCell(i).SetCellValue(cellValue);
  676. }
  677. }
  678. else
  679. {
  680. // 3.4 填充到Excel的单元格里
  681. rowTmp.CreateCell(i).SetCellValue(cellValue);
  682. }
  683. }
  684. rowIndex++;
  685. }
  686. // 4.生成文件
  687. FileStream file = new FileStream($"{path}{fileName}", FileMode.Create);
  688. workbook.Write(file);
  689. file.Close();
  690. lcRetVal = $"{filePath}{fileName}";
  691. }
  692. catch (Exception ex)
  693. {
  694. lcRetVal += ex.Message;
  695. //typeof(ExcelHelper).LogError(ex);
  696. }
  697. return lcRetVal;
  698. }
  699. public static string EntityListToExcel2003(this HSSFWorkbook workbook,
  700. string sheetName, string filePath)
  701. {
  702. var lcRetVal = "error@";
  703. try
  704. {
  705. string fileName = $"D-{sheetName}-{DateTime.Now:yyyyMMddHHmmssfff}.xls"; // 文件名称
  706. filePath = filePath.StartsWith("/") ? filePath : ("/" + filePath);
  707. filePath = filePath.EndsWith("/") ? filePath : (filePath + "/");
  708. string path = $"{AppDomain.CurrentDomain.BaseDirectory}{filePath}";
  709. if (!Directory.Exists(path))
  710. Directory.CreateDirectory(path);
  711. FileStream file = new FileStream($"{path}{fileName}", FileMode.Create);
  712. workbook.Write(file);
  713. file.Close();
  714. lcRetVal = $"{filePath}{fileName}";
  715. }
  716. catch (Exception ex)
  717. {
  718. lcRetVal += ex.Message;
  719. //typeof(ExcelHelper).LogError(ex);
  720. }
  721. return lcRetVal;
  722. }
  723. public static HSSFWorkbook EntityListToExcel2003Book(this Dictionary<string, string> cellHeader, IList enList,
  724. string sheetName)
  725. {
  726. HSSFWorkbook workbook = new HSSFWorkbook(); // 工作簿
  727. ISheet sheet = workbook.CreateSheet(sheetName); // 工作表
  728. IRow row = sheet.CreateRow(0);
  729. List<string> keys = cellHeader.Keys.ToList();
  730. for (int i = 0; i < keys.Count; i++)
  731. {
  732. row.CreateCell(i).SetCellValue(cellHeader[keys[i]]); // 列名为Key的值
  733. }
  734. // 3.List对象的值赋值到Excel的单元格里
  735. int rowIndex = 1; // 从第二行开始赋值(第一行已设置为单元头)
  736. foreach (var en in enList)
  737. {
  738. IRow rowTmp = sheet.CreateRow(rowIndex);
  739. for (int i = 0; i < keys.Count; i++) // 根据指定的属性名称,获取对象指定属性的值
  740. {
  741. string cellValue = ""; // 单元格的值
  742. object propertyValue = null; // 属性的值
  743. PropertyInfo propertyInfo; // 属性的信息
  744. // 3.1 若属性头的名称包含'.',就表示是子类里的属性,那么就要遍历子类,eg:UserEn.UserName
  745. if (keys[i].IndexOf(".", StringComparison.Ordinal) >= 0)
  746. {
  747. // 3.1.1 解析子类属性(这里只解析1层子类,多层子类未处理)
  748. string[] propertyArray = keys[i].Split(new[] { "." }, StringSplitOptions.RemoveEmptyEntries);
  749. string subClassName = propertyArray[0]; // '.'前面的为子类的名称
  750. string subClassPropertyName = propertyArray[1]; // '.'后面的为子类的属性名称
  751. PropertyInfo subClassInfo = en.GetType().GetProperty(subClassName); // 获取子类的类型
  752. if (subClassInfo != null)
  753. {
  754. // 3.1.2 获取子类的实例
  755. var subClassEn = en.GetType().GetProperty(subClassName)?.GetValue(en, null);
  756. // 3.1.3 根据属性名称获取子类里的属性类型
  757. propertyInfo = subClassInfo.PropertyType.GetProperty(subClassPropertyName);
  758. if (propertyInfo != null)
  759. {
  760. propertyValue = propertyInfo.GetValue(subClassEn, null); // 获取子类属性的值
  761. }
  762. }
  763. }
  764. else
  765. {
  766. // 3.2 若不是子类的属性,直接根据属性名称获取对象对应的属性
  767. propertyInfo = en.GetType().GetProperty(keys[i]);
  768. if (propertyInfo != null)
  769. {
  770. propertyValue = propertyInfo.GetValue(en, null);
  771. }
  772. }
  773. // 3.3 属性值经过转换赋值给单元格值
  774. if (propertyValue != null)
  775. {
  776. cellValue = propertyValue.ToString();
  777. // 3.3.1 对时间初始值赋值为空
  778. if (cellValue.Trim() == "0001/1/1 0:00:00" || cellValue.Trim() == "0001/1/1 23:59:59")
  779. {
  780. cellValue = "";
  781. }
  782. }
  783. // 3.4 填充到Excel的单元格里
  784. rowTmp.CreateCell(i).SetCellValue(cellValue);
  785. }
  786. rowIndex++;
  787. }
  788. return workbook;
  789. }
  790. /// <summary>
  791. /// 实体类集合导出到EXCEL2007
  792. /// </summary>
  793. /// <param name="cellHeader">单元头的Key和Value:{ { "UserName", "姓名" }, { "Age", "年龄" } };</param>
  794. /// <param name="enList">数据源</param>
  795. /// <param name="sheetName">工作表名称</param>
  796. /// <param name="filePath">文件的下载地址</param>
  797. /// <returns></returns>
  798. public static string EntityListToExcel2007(this Dictionary<string, string> cellHeader, IList enList, string sheetName, string filePath)
  799. {
  800. var lcRetVal = "error@";
  801. try
  802. {
  803. string fileName = $"D-{sheetName}-{DateTime.Now:yyyyMMddHHmmssfff}.xlsx"; // 文件名称
  804. filePath = filePath.StartsWith("/") ? filePath : ("/" + filePath);
  805. filePath = filePath.EndsWith("/") ? filePath : (filePath + "/");
  806. string path = $"{AppDomain.CurrentDomain.BaseDirectory}{filePath}";
  807. if (!Directory.Exists(path))
  808. Directory.CreateDirectory(path);
  809. // 2.解析单元格头部,设置单元头的中文名称
  810. XSSFWorkbook workbook = new XSSFWorkbook(); // 工作簿
  811. ISheet sheet = workbook.CreateSheet(sheetName); // 工作表
  812. IRow row = sheet.CreateRow(0);
  813. List<string> keys = cellHeader.Keys.ToList();
  814. for (int i = 0; i < keys.Count; i++)
  815. {
  816. row.CreateCell(i).SetCellValue(cellHeader[keys[i]]); // 列名为Key的值
  817. }
  818. // 3.List对象的值赋值到Excel的单元格里
  819. int rowIndex = 1; // 从第二行开始赋值(第一行已设置为单元头)
  820. foreach (var en in enList)
  821. {
  822. IRow rowTmp = sheet.CreateRow(rowIndex);
  823. for (int i = 0; i < keys.Count; i++) // 根据指定的属性名称,获取对象指定属性的值
  824. {
  825. string cellValue = ""; // 单元格的值
  826. object propertyValue = null; // 属性的值
  827. PropertyInfo propertyInfo = null; // 属性的信息
  828. // 3.1 若属性头的名称包含'.',就表示是子类里的属性,那么就要遍历子类,eg:UserEn.UserName
  829. if (keys[i].IndexOf(".", StringComparison.Ordinal) >= 0)
  830. {
  831. // 3.1.1 解析子类属性(这里只解析1层子类,多层子类未处理)
  832. string[] propertyArray = keys[i].Split(new[] { "." }, StringSplitOptions.RemoveEmptyEntries);
  833. string subClassName = propertyArray[0]; // '.'前面的为子类的名称
  834. var subClassPropertyName = propertyArray[1]; // '.'后面的为子类的属性名称
  835. PropertyInfo subClassInfo = en.GetType().GetProperty(subClassName); // 获取子类的类型
  836. if (subClassInfo != null)
  837. {
  838. // 3.1.2 获取子类的实例
  839. var subClassEn = en.GetType().GetProperty(subClassName)?.GetValue(en, null);
  840. // 3.1.3 根据属性名称获取子类里的属性类型
  841. propertyInfo = subClassInfo.PropertyType.GetProperty(subClassPropertyName);
  842. if (propertyInfo != null)
  843. {
  844. propertyValue = propertyInfo.GetValue(subClassEn, null); // 获取子类属性的值
  845. }
  846. }
  847. }
  848. else
  849. {
  850. // 3.2 若不是子类的属性,直接根据属性名称获取对象对应的属性
  851. propertyInfo = en.GetType().GetProperty(keys[i]);
  852. if (propertyInfo != null)
  853. {
  854. propertyValue = propertyInfo.GetValue(en, null);
  855. }
  856. }
  857. // 3.3 属性值经过转换赋值给单元格值
  858. if (propertyValue != null)
  859. {
  860. if (propertyInfo.PropertyType.Name.ToLower() == "int" || propertyInfo.PropertyType.Name.ToLower() == "int16" || propertyInfo.PropertyType.Name.ToLower() == "int32" || propertyInfo.PropertyType.Name.ToLower() == "int64" || propertyInfo.PropertyType.Name.ToLower() == "double" || propertyInfo.PropertyType.Name.ToLower() == "decimal")
  861. {
  862. var value = Convert.ToDouble(propertyValue);
  863. rowTmp.CreateCell(i).SetCellValue(value);
  864. }
  865. else if (propertyInfo.PropertyType.Name.ToLower() == "bool")
  866. {
  867. var value = Convert.ToBoolean(propertyValue);
  868. rowTmp.CreateCell(i).SetCellValue(value);
  869. }
  870. else if (propertyInfo.PropertyType.Name.ToLower() == "nullable`1")
  871. {
  872. if (propertyInfo.PropertyType.FullName == null)
  873. {
  874. }
  875. else if (propertyInfo.PropertyType.FullName.ToLower().Contains("datetime"))
  876. {
  877. cellValue = propertyValue.ToString();
  878. // 3.3.1 对时间初始值赋值为空
  879. if (cellValue.Trim() == "0001/1/1 0:00:00" || cellValue.Trim() == "0001/1/1 23:59:59")
  880. {
  881. cellValue = "";
  882. }
  883. rowTmp.CreateCell(i).SetCellValue(cellValue);
  884. }
  885. else if (propertyInfo.PropertyType.FullName.ToLower().Contains("int"))
  886. {
  887. var value = (int)Convert.ChangeType(propertyValue, typeof(int));
  888. rowTmp.CreateCell(i).SetCellValue(value);
  889. }
  890. else if (propertyInfo.PropertyType.FullName.ToLower().Contains("float") || propertyInfo.PropertyType.FullName.ToLower().Contains("double") || propertyInfo.PropertyType.FullName.ToLower().Contains("decimal") || propertyInfo.PropertyType.FullName.ToLower().Contains("single"))
  891. {
  892. var value = (float)Convert.ChangeType(propertyValue, typeof(float));
  893. rowTmp.CreateCell(i).SetCellValue(value);
  894. }
  895. else if (propertyInfo.PropertyType.FullName.ToLower().Contains("bool"))
  896. {
  897. var value = (bool)Convert.ChangeType(propertyValue, typeof(bool));
  898. rowTmp.CreateCell(i).SetCellValue(value);
  899. }
  900. }
  901. else
  902. {
  903. cellValue = propertyValue.ToString();
  904. // 3.3.1 对时间初始值赋值为空
  905. if (cellValue.Trim() == "0001/1/1 0:00:00" || cellValue.Trim() == "0001/1/1 23:59:59")
  906. {
  907. cellValue = "";
  908. }
  909. // 3.4 填充到Excel的单元格里
  910. rowTmp.CreateCell(i).SetCellValue(cellValue);
  911. }
  912. }
  913. else
  914. {
  915. // 3.4 填充到Excel的单元格里
  916. rowTmp.CreateCell(i).SetCellValue(cellValue);
  917. }
  918. }
  919. rowIndex++;
  920. }
  921. // 4.生成文件
  922. FileStream file = new FileStream($"{path}{fileName}", FileMode.Create);
  923. workbook.Write(file);
  924. file.Close();
  925. lcRetVal = $"{filePath}{fileName}";
  926. }
  927. catch (Exception ex)
  928. {
  929. lcRetVal += ex.Message;
  930. //typeof(ExcelHelper).LogError(ex);
  931. }
  932. return lcRetVal;
  933. }
  934. #endregion Excel导出
  935. #region Common
  936. /// <summary>
  937. /// Excel row转换为实体对象
  938. /// </summary>
  939. /// <typeparam name="T"></typeparam>
  940. /// <param name="cellHeader">单元头的Key和Value:{ { "UserName", "姓名" }, { "Age", "年龄" } };</param>
  941. /// <param name="row">Excel row</param>
  942. /// <param name="rowIndex">row index</param>
  943. /// <param name="en">实体</param>
  944. /// <param name="errorMsg">错误信息</param>
  945. private static void ExcelRowToEntity<T>(Dictionary<string, string> cellHeader, IRow row, int rowIndex, T en, ref StringBuilder errorMsg)
  946. {
  947. List<string> keys = cellHeader.Keys.ToList(); // 要赋值的实体对象属性名称
  948. string errStr = ""; // 当前行转换时,是否有错误信息,格式为:第1行数据转换异常:XXX列;
  949. for (int i = 0; i < keys.Count; i++)
  950. {
  951. // 1.若属性头的名称包含'.',就表示是子类里的属性,那么就要遍历子类,eg:UserEn.TrueName
  952. if (keys[i].IndexOf(".", StringComparison.Ordinal) >= 0)
  953. {
  954. // 1)解析子类属性
  955. string[] propertyArray = keys[i].Split(new[] { "." }, StringSplitOptions.RemoveEmptyEntries);
  956. string subClassName = propertyArray[0]; // '.'前面的为子类的名称
  957. string classPropertyName = propertyArray[1]; // '.'后面的为子类的属性名称
  958. PropertyInfo subClassInfo = en.GetType().GetProperty(subClassName); // 获取子类的类型
  959. if (subClassInfo != null)
  960. {
  961. // 2)获取子类的实例
  962. var subClassEn = en.GetType().GetProperty(subClassName)?.GetValue(en, null);
  963. // 3)根据属性名称获取子类里的属性信息
  964. PropertyInfo propertyInfo = subClassInfo.PropertyType.GetProperty(classPropertyName);
  965. if (propertyInfo != null)
  966. {
  967. try
  968. {
  969. // Excel单元格的值转换为对象属性的值,若类型不对,记录出错信息
  970. propertyInfo.SetValue(subClassEn, GetExcelCellToProperty(propertyInfo.PropertyType, row.GetCell(i)), null);
  971. }
  972. catch (Exception e)
  973. {
  974. //typeof(ExcelHelper).LogError(e);
  975. if (errStr.Length == 0)
  976. {
  977. errStr = "第" + rowIndex + "行数据转换异常:";
  978. }
  979. errStr += cellHeader[keys[i]] + "列;";
  980. }
  981. }
  982. }
  983. }
  984. else
  985. {
  986. // 2.给指定的属性赋值
  987. PropertyInfo propertyInfo = en.GetType().GetProperty(keys[i]);
  988. if (propertyInfo != null)
  989. {
  990. try
  991. {
  992. // Excel单元格的值转换为对象属性的值,若类型不对,记录出错信息
  993. propertyInfo.SetValue(en, GetExcelCellToProperty(propertyInfo.PropertyType, row.GetCell(i)), null);
  994. }
  995. catch (Exception e)
  996. {
  997. //typeof(ExcelHelper).LogError(e);
  998. if (errStr.Length == 0)
  999. {
  1000. errStr = "第" + rowIndex + "行数据转换异常:";
  1001. }
  1002. errStr += cellHeader[keys[i]] + "列;";
  1003. }
  1004. }
  1005. }
  1006. }
  1007. // 若有错误信息,就添加到错误信息里
  1008. if (errStr.Length > 0)
  1009. {
  1010. errorMsg.AppendLine(errStr);
  1011. }
  1012. }
  1013. /// <summary>
  1014. /// Excel Cell转换为实体的属性值
  1015. /// </summary>
  1016. /// <param name="distanceType">目标对象类型</param>
  1017. /// <param name="sourceCell">对象属性的值</param>
  1018. private static object GetExcelCellToProperty(Type distanceType, ICell sourceCell)
  1019. {
  1020. object rs = distanceType.IsValueType ? Activator.CreateInstance(distanceType) : null;
  1021. // 1.判断传递的单元格是否为空
  1022. if (sourceCell == null || string.IsNullOrEmpty(sourceCell.ToString()))
  1023. {
  1024. return rs;
  1025. }
  1026. // 2.Excel文本和数字单元格转换,在Excel里文本和数字是不能进行转换,所以这里预先存值
  1027. object sourceValue = null;
  1028. switch (sourceCell.CellType)
  1029. {
  1030. case CellType.Blank:
  1031. break;
  1032. case CellType.Boolean:
  1033. sourceValue = sourceCell.BooleanCellValue;
  1034. break;
  1035. case CellType.Error:
  1036. break;
  1037. case CellType.Formula:
  1038. break;
  1039. case CellType.Numeric:
  1040. sourceValue = sourceCell.NumericCellValue;
  1041. break;
  1042. case CellType.String:
  1043. sourceValue = sourceCell.StringCellValue;
  1044. break;
  1045. case CellType.Unknown:
  1046. break;
  1047. default:
  1048. sourceValue = sourceCell.StringCellValue;
  1049. break;
  1050. }
  1051. string valueDataType = distanceType.Name;
  1052. // 在这里进行特定类型的处理
  1053. switch (valueDataType.ToLower()) // 以防出错,全部小写
  1054. {
  1055. case "string":
  1056. rs = sourceValue?.ToString();
  1057. break;
  1058. case "int":
  1059. case "int32":
  1060. rs = (int)Convert.ChangeType(sourceValue?.ToString() ?? "", distanceType);
  1061. break;
  1062. case "int16":
  1063. rs = (short)Convert.ChangeType(sourceValue?.ToString() ?? "", distanceType);
  1064. break;
  1065. case "int64":
  1066. rs = (long)Convert.ChangeType(sourceValue?.ToString() ?? "", distanceType);
  1067. break;
  1068. case "float":
  1069. case "single":
  1070. rs = (float)Convert.ChangeType(sourceValue?.ToString() ?? "", distanceType);
  1071. break;
  1072. case "double":
  1073. rs = (double)Convert.ChangeType(sourceValue?.ToString() ?? "", distanceType);
  1074. break;
  1075. case "decimal":
  1076. rs = (decimal)Convert.ChangeType(sourceValue?.ToString() ?? "", distanceType);
  1077. break;
  1078. case "datetime":
  1079. rs = (DateTime)Convert.ChangeType(sourceValue?.ToString() ?? "", distanceType);
  1080. break;
  1081. case "guid":
  1082. rs = (Guid)Convert.ChangeType(sourceValue?.ToString() ?? "", distanceType);
  1083. break;
  1084. case "nullable`1":
  1085. if (distanceType.FullName == null)
  1086. {
  1087. rs = "";
  1088. }
  1089. else if (distanceType.FullName.ToLower().Contains("datetime"))
  1090. {
  1091. rs = (DateTime)Convert.ChangeType(sourceValue?.ToString() ?? "", typeof(DateTime));
  1092. }
  1093. else if ((bool)distanceType.FullName?.ToLower().Contains("int"))
  1094. {
  1095. rs = (int)Convert.ChangeType(sourceValue?.ToString() ?? "", typeof(int));
  1096. }
  1097. else if ((bool)distanceType.FullName?.ToLower().Contains("float") || (bool)distanceType.FullName?.ToLower().Contains("double") || (bool)distanceType.FullName?.ToLower().Contains("decimal") || (bool)distanceType.FullName?.ToLower().Contains("single"))
  1098. {
  1099. rs = (float)Convert.ChangeType(sourceValue?.ToString() ?? "", typeof(float));
  1100. }
  1101. else if ((bool)distanceType.FullName?.ToLower().Contains("bool"))
  1102. {
  1103. rs = (bool)Convert.ChangeType(sourceValue?.ToString() ?? "", typeof(bool));
  1104. }
  1105. break;
  1106. }
  1107. return rs;
  1108. }
  1109. #endregion
  1110. public static HSSFWorkbook CreateWorkBook03(string filePath = null)
  1111. {
  1112. if (string.IsNullOrEmpty(filePath))
  1113. {
  1114. return new HSSFWorkbook();
  1115. }
  1116. FileStream file = new FileStream(filePath, FileMode.Open);
  1117. return new HSSFWorkbook(file);
  1118. }
  1119. public static XSSFWorkbook CreateWorkBook07(string filePath = null)
  1120. {
  1121. if (string.IsNullOrEmpty(filePath))
  1122. {
  1123. return new XSSFWorkbook();
  1124. }
  1125. return new XSSFWorkbook(filePath);
  1126. }
  1127. /// <summary>
  1128. /// 创建Sheet
  1129. /// </summary>
  1130. /// <param name="sheetName"></param>
  1131. /// <param name="defaultWidth"></param>
  1132. /// <param name="defaultHeight"></param>
  1133. /// <param name="is07"></param>
  1134. /// <param name="workbook"></param>
  1135. /// <returns></returns>
  1136. public static ISheet GenerateSheet(this string sheetName, int defaultWidth = 20, int defaultHeight = 20, bool is07 = true, IWorkbook workbook = null)
  1137. {
  1138. workbook = is07 ? workbook ?? CreateWorkBook07() : workbook ?? CreateWorkBook03();
  1139. var sheet = workbook.CreateSheet(sheetName);
  1140. sheet.DefaultColumnWidth = defaultWidth;
  1141. sheet.DefaultRowHeight = (short)(defaultHeight * 20);
  1142. return sheet;
  1143. }
  1144. /// <summary>
  1145. /// 创建行
  1146. /// </summary>
  1147. /// <param name="sheet">表</param>
  1148. /// <param name="rowIndex">第几行(从1开始计数)</param>
  1149. /// <returns></returns>
  1150. public static IRow GenerateRow(this ISheet sheet, int rowIndex)
  1151. {
  1152. rowIndex = rowIndex <= 0 ? 1 : rowIndex;
  1153. var row = sheet.GetRow(rowIndex - 1) ?? sheet.CreateRow(rowIndex - 1);
  1154. return row;
  1155. }
  1156. /// <summary>
  1157. /// 创建单元格
  1158. /// </summary>
  1159. /// <param name="sheet">表</param>
  1160. /// <param name="rowIndex">第几行(从1开始计数)</param>
  1161. /// <param name="columnIndex">第几列(从1开始计数)</param>
  1162. /// <param name="val">值</param>
  1163. /// <param name="cellType">单元格类型</param>
  1164. /// <returns></returns>
  1165. public static ICell GenerateCell(this ISheet sheet, int rowIndex, int columnIndex, string val = null, CellType cellType = CellType.String)
  1166. {
  1167. var row = sheet.GenerateRow(rowIndex);
  1168. var cell = GenerateCell(row, columnIndex, val, cellType);
  1169. return cell;
  1170. }
  1171. /// <summary>
  1172. /// 创建单元格
  1173. /// </summary>
  1174. /// <param name="row">行</param>
  1175. /// <param name="columnIndex">第几列(从1开始计数)</param>
  1176. /// <param name="val">值</param>
  1177. /// <param name="cellType">单元格类型</param>
  1178. /// <returns></returns>
  1179. public static ICell GenerateCell(this IRow row, int columnIndex, string val = null, CellType cellType = CellType.String)
  1180. {
  1181. columnIndex = columnIndex <= 0 ? 1 : columnIndex;
  1182. var cell = row.GetCell(columnIndex - 1) ?? row.CreateCell(columnIndex - 1);
  1183. if (!string.IsNullOrEmpty(val))
  1184. {
  1185. cell.SetCellValue(val);
  1186. cell.SetCellType(cellType);
  1187. }
  1188. return cell;
  1189. }
  1190. /// <summary>
  1191. /// 设置列宽度
  1192. /// </summary>
  1193. /// <param name="sheet">表</param>
  1194. /// <param name="columnIndex">第几列(从1开始计数)</param>
  1195. /// <param name="width">宽度</param>
  1196. /// <returns></returns>
  1197. public static ISheet SetCellWidth(this ISheet sheet, int columnIndex, int width)
  1198. {
  1199. sheet.SetColumnWidth(columnIndex - 1, width * 256);
  1200. return sheet;
  1201. }
  1202. /// <summary>
  1203. /// 设置列宽度
  1204. /// </summary>
  1205. /// <param name="row">行</param>
  1206. /// <param name="columnIndex">第几列(从1开始计数)</param>
  1207. /// <param name="width">宽度</param>
  1208. /// <returns></returns>
  1209. public static IRow SetCellWidth(this IRow row, int columnIndex, int width)
  1210. {
  1211. row.Sheet.SetColumnWidth(columnIndex - 1, width * 256);
  1212. return row;
  1213. }
  1214. /// <summary>
  1215. /// 设置列宽度
  1216. /// </summary>
  1217. /// <param name="cell">单元格</param>
  1218. /// <param name="columnIndex">第几列(从1开始计数)</param>
  1219. /// <param name="width">宽度</param>
  1220. /// <returns></returns>
  1221. public static ICell SetCellWidth(this ICell cell, int columnIndex, int width)
  1222. {
  1223. cell.Sheet.SetColumnWidth(columnIndex - 1, width * 256);
  1224. return cell;
  1225. }
  1226. /// <summary>
  1227. /// 设置行高度
  1228. /// </summary>
  1229. /// <param name="sheet">表</param>
  1230. /// <param name="rowIndex">第几行(从1开始计数)</param>
  1231. /// <param name="height">宽度</param>
  1232. /// <returns></returns>
  1233. public static ISheet SetRowHeight(this ISheet sheet, int rowIndex, int height)
  1234. {
  1235. sheet.GetRow(rowIndex - 1).SetRowHeight(height);
  1236. return sheet;
  1237. }
  1238. /// <summary>
  1239. /// 设置行高度
  1240. /// </summary>
  1241. /// <param name="row">行</param>
  1242. /// <param name="height">宽度</param>
  1243. /// <returns></returns>
  1244. public static IRow SetRowHeight(this IRow row, int height)
  1245. {
  1246. row.Height = (short)(height * 20);
  1247. return row;
  1248. }
  1249. /// <summary>
  1250. /// 设置行高度
  1251. /// </summary>
  1252. /// <param name="cell">单元格</param>
  1253. /// <param name="height">宽度</param>
  1254. /// <returns></returns>
  1255. public static ICell SetRowHeight(this ICell cell, int height)
  1256. {
  1257. cell.Row.SetRowHeight(height);
  1258. return cell;
  1259. }
  1260. /// <summary>
  1261. /// 设置单元格的值
  1262. /// </summary>
  1263. /// <param name="cell"></param>
  1264. /// <param name="obj"></param>
  1265. /// <returns></returns>
  1266. public static ICell SetValue(this ICell cell, string obj)
  1267. {
  1268. return SetValue<string>(cell, obj);
  1269. }
  1270. /// <summary>
  1271. /// 设置单元格的值
  1272. /// </summary>
  1273. /// <typeparam name="T">值类型(sting,bool,double,DateTime)</typeparam>
  1274. /// <param name="cell"></param>
  1275. /// <param name="obj"></param>
  1276. /// <returns></returns>
  1277. public static ICell SetValue<T>(this ICell cell, object obj)
  1278. {
  1279. Type type = typeof(T);
  1280. bool bValue;
  1281. double iValue;
  1282. DateTime dValue;
  1283. if (type == typeof(string))
  1284. {
  1285. cell.SetCellValue(obj.ToString());
  1286. }
  1287. else if (type == typeof(bool) && bool.TryParse(obj.ToString(), out bValue))
  1288. {
  1289. cell.SetCellValue(bValue);
  1290. }
  1291. else if ((type == typeof(int) || type == typeof(double) || type == typeof(decimal)) && double.TryParse(obj.ToString(), out iValue))
  1292. {
  1293. cell.SetCellValue(iValue);
  1294. }
  1295. else if (type == typeof(DateTime) && DateTime.TryParse(obj.ToString(), out dValue))
  1296. {
  1297. cell.SetCellValue(dValue);
  1298. }
  1299. return cell;
  1300. }
  1301. #region DATA-FORMAT
  1302. public static ICellStyle SetCellDateTime(this ICell cell, DateTime value, string formatStr = "yyyy-MM-dd HH:mm:ss")
  1303. {
  1304. cell.SetCellValue(value);
  1305. cell.SetDataFormat(formatStr);
  1306. return cell.CellStyle;
  1307. }
  1308. public static ICellStyle SetCellString(this ICell cell, double value, string formatStr = "@")
  1309. {
  1310. cell.SetCellValue(value);
  1311. cell.SetDataFormat(formatStr);
  1312. return cell.CellStyle;
  1313. }
  1314. public static ICellStyle SetCellDouble(this ICell cell, double value, string formatStr = "0.00")
  1315. {
  1316. cell.SetCellValue(value);
  1317. cell.SetDataFormat(formatStr);
  1318. return cell.CellStyle;
  1319. }
  1320. public static ICellStyle SetCellCurrency(this ICell cell, double value, string formatStr = "¥#,###.##")
  1321. {
  1322. cell.SetCellValue(value);
  1323. cell.SetDataFormat(formatStr);
  1324. return cell.CellStyle;
  1325. }
  1326. public static ICellStyle SetCellPercent(this ICell cell, double value, string formatStr = "0.00%")
  1327. {
  1328. cell.SetCellValue(value);
  1329. cell.SetDataFormat(formatStr);
  1330. return cell.CellStyle;
  1331. }
  1332. public static void SetDataFormat(this ICell cell, string formatStr = "¥#,##0.00")
  1333. {
  1334. var cellStyle = cell.CellStyle ?? GetCellStyle(cell);
  1335. var format = cell.Sheet.Workbook.CreateDataFormat();
  1336. cellStyle.DataFormat = format.GetFormat(formatStr);
  1337. cell.SetCellStyle(cellStyle);
  1338. }
  1339. #endregion
  1340. #region 合并单元格
  1341. /// <summary>
  1342. /// 合并单元格
  1343. /// </summary>
  1344. /// <param name="sheet"></param>
  1345. /// <param name="firstRow">开始行数(从1开始计数)</param>
  1346. /// <param name="lastRow">结束行数(从1开始计数)</param>
  1347. /// <param name="firstColumn">开始列数(从1开始计数)</param>
  1348. /// <param name="lastColumn">结束列数(从1开始计数)</param>
  1349. /// <returns></returns>
  1350. public static ISheet MergedRegion(this ISheet sheet, int firstRow, int lastRow, int firstColumn, int lastColumn)
  1351. {
  1352. var region = GetCellRegion(firstRow, lastRow, firstColumn, lastColumn);
  1353. sheet.MergedRegion(region);
  1354. return sheet;
  1355. }
  1356. public static ISheet MergedRegion(this ISheet sheet, CellRangeAddress region)
  1357. {
  1358. sheet.AddMergedRegion(region);
  1359. //SetRegionBorder(sheet, region, borderTypeStr, borderColorStr);
  1360. return sheet;
  1361. }
  1362. public static CellRangeAddress GetCellRegion(this int firstRow, int lastRow, int firstColumn, int lastColumn)
  1363. {
  1364. firstRow = firstRow <= 0 ? 1 : firstRow;
  1365. firstColumn = firstColumn <= 0 ? 1 : firstColumn;
  1366. lastRow = lastRow <= 0 ? 1 : lastRow;
  1367. lastColumn = lastColumn <= 0 ? 1 : lastColumn;
  1368. return new CellRangeAddress(firstRow - 1, lastRow - 1, firstColumn - 1, lastColumn - 1);
  1369. }
  1370. #endregion
  1371. public static ICellStyle GetCellStyle(this ICell cell)
  1372. {
  1373. return cell.CellStyle ?? cell.Sheet.Workbook.CreateCellStyle();
  1374. }
  1375. public static void SetCellStyle(this ICell cell, ICellStyle cellStyle)
  1376. {
  1377. cell.CellStyle = cellStyle;
  1378. }
  1379. /// <summary>
  1380. /// 保存工作簿
  1381. /// </summary>
  1382. /// <param name="sheet"></param>
  1383. /// <param name="filePath"></param>
  1384. /// <param name="fileName"></param>
  1385. /// <returns></returns>
  1386. public static string SaveWorkBook(this ISheet sheet, string filePath, string fileName)
  1387. {
  1388. try
  1389. {
  1390. if (!Directory.Exists(filePath))
  1391. {
  1392. Directory.CreateDirectory(filePath);
  1393. }
  1394. filePath = filePath.EndsWith("\\") ? filePath : filePath + "\\";
  1395. FileStream file = new FileStream(filePath + fileName, FileMode.Create);
  1396. sheet.Workbook.Write(file);
  1397. file.Close();
  1398. return "";
  1399. }
  1400. catch (Exception e)
  1401. {
  1402. return e.Message;
  1403. }
  1404. }
  1405. /// <summary>
  1406. /// 保存工作簿
  1407. /// </summary>
  1408. /// <param name="workbook"></param>
  1409. /// <param name="filePath"></param>
  1410. /// <param name="fileName"></param>
  1411. /// <returns></returns>
  1412. public static string SaveWorkBook(this IWorkbook workbook, string filePath, string fileName)
  1413. {
  1414. try
  1415. {
  1416. if (!Directory.Exists(filePath))
  1417. {
  1418. Directory.CreateDirectory(filePath);
  1419. }
  1420. filePath = filePath.EndsWith("\\") ? filePath : filePath + "\\";
  1421. var path = filePath + fileName;
  1422. if (File.Exists(path))
  1423. {
  1424. File.Delete(path);
  1425. }
  1426. FileStream file = new FileStream(path, FileMode.Create);
  1427. workbook.Write(file);
  1428. file.Close();
  1429. return "";
  1430. }
  1431. catch (Exception e)
  1432. {
  1433. return e.Message;
  1434. }
  1435. }
  1436. }
  1437. }