前端转vue
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

AnalyzeFile.cs 41KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.IO;
  6. using System.Data;
  7. using System.Data.OleDb;
  8. using Microsoft.Win32;
  9. using System.Runtime.InteropServices;
  10. using Platform.Common.LogSystem;
  11. using System.Security.Cryptography;
  12. //add by wangfei 2012/12/14 16:00
  13. namespace TellerSystem.Library.Ext.TradeExtension
  14. {
  15. /// <summary>
  16. /// 解析文件
  17. /// </summary>
  18. public class AnalyzeFile
  19. {
  20. #region 变量
  21. //文件路径
  22. private string path;
  23. //Excel的Sheet节点集合
  24. private List<string> listSheet;
  25. //Excel按照的版本
  26. private static string excelVerson;
  27. //编码方式
  28. private Encoding txt_EnCode;
  29. //行分隔符
  30. private char[] txt_LineSplit;
  31. //列分隔符
  32. private char txt_ColSplit;
  33. private StreamReader txt_FileStream = null;
  34. //文件流打开标志
  35. private bool m_OpenFlag = false;
  36. #endregion
  37. #region 方法
  38. /// <summary>
  39. /// 解析文本文件导入数据
  40. /// </summary>
  41. /// <param name="txt_RowSplit">行分隔符</param>
  42. /// <param name="txt_ColumnSlit">列分割符</param>
  43. /// <param name="txt_EnCode">编码方式</param>
  44. /// <param name="isColumnHeader">是否显示列头</param>
  45. /// <returns>返回一个DataTable</returns>
  46. public DataTable AnalyzeTxtData(char[] txt_RowSplit, char txt_ColumnSlit, string txt_EnCode, bool isColumnHeader = true)
  47. {
  48. DataTable dataTabel = null;
  49. m_OpenFlag = true;
  50. //匹配标志
  51. bool flag = false;
  52. //当前行数
  53. int rowCount = 0;
  54. List<string> lineData = new List<string>();
  55. if (txt_RowSplit == null)//分割符
  56. {
  57. return null;
  58. }
  59. if (txt_RowSplit.Length == 0)//行分割符
  60. {
  61. return null;
  62. }
  63. if (string.IsNullOrWhiteSpace(txt_ColumnSlit.ToString()))//列分割符
  64. {
  65. return null;
  66. }
  67. if (string.IsNullOrWhiteSpace(txt_EnCode))//编码方式
  68. {
  69. return null;
  70. }
  71. OpenFile(out path);
  72. //打开文件读取流
  73. if (!File.Exists(path))//文件不存在
  74. {
  75. return null;
  76. }
  77. this.txt_EnCode = Encoding.GetEncoding(txt_EnCode);
  78. //行分割符字符数组,当前只支持最大两个字符的分隔符
  79. char[] tmpStrs = txt_RowSplit;
  80. byte[] lineByte = new byte[tmpStrs.Length];
  81. for (int k = 0; k < tmpStrs.Length; k++)
  82. {
  83. lineByte[k] = Convert.ToByte(Convert.ToInt32(tmpStrs[k]));
  84. }
  85. this.txt_LineSplit = this.txt_EnCode.GetChars(lineByte);
  86. //列分割符
  87. byte[] fieldByte = new byte[1];
  88. char[] fieldSplit = new char[1];
  89. fieldByte[0] = Convert.ToByte(Convert.ToInt32(txt_ColumnSlit));
  90. fieldSplit = this.txt_EnCode.GetChars(fieldByte);
  91. this.txt_ColSplit = fieldSplit[0];
  92. txt_FileStream = new StreamReader(path, this.txt_EnCode, true);
  93. char temp;
  94. StringBuilder rowData = new StringBuilder();
  95. int readCount = 0;
  96. //循环处理所有流数据
  97. while (!txt_FileStream.EndOfStream)
  98. {
  99. //当前处理字符
  100. temp = (char)txt_FileStream.Read();
  101. readCount++;
  102. //当前为第二个字符匹配时执行
  103. if (flag)
  104. {
  105. //匹配不成功
  106. if (temp != this.txt_LineSplit[1])
  107. {
  108. rowData.Append(this.txt_LineSplit[0]);
  109. rowData.Append(temp);
  110. flag = false;
  111. //不是最后一个字符
  112. if (!txt_FileStream.EndOfStream)
  113. {
  114. continue;
  115. }
  116. }
  117. //匹配成功
  118. else
  119. {
  120. flag = false;
  121. }
  122. }
  123. else
  124. {
  125. //第一个字符匹配成功设置匹配成功标志
  126. if (temp == this.txt_LineSplit[0])
  127. {
  128. //两个字符的情况
  129. if (this.txt_LineSplit.Length == 2)
  130. {
  131. flag = true;
  132. //不是最后一个字符
  133. if (!txt_FileStream.EndOfStream)
  134. {
  135. continue;
  136. }
  137. else
  138. {
  139. rowData.Append(temp);
  140. }
  141. }
  142. }
  143. //第一个匹配不成功时按正常数据处理
  144. else
  145. {
  146. rowData.Append(temp);
  147. flag = false;
  148. //不是最后一个字符
  149. if (!txt_FileStream.EndOfStream)
  150. {
  151. if (readCount > 100000)
  152. {
  153. throw new Exception("找到不到指定的行分割符");
  154. }
  155. continue;
  156. }
  157. }
  158. }
  159. lineData.Add(rowData.ToString());
  160. rowData.Clear();
  161. //设置当前行数
  162. rowCount += 1;
  163. //行读取字符个数 清零
  164. readCount = 0;
  165. }
  166. //第一行是否为字段名称
  167. DataTable data = new DataTable("Table_Sheet1");
  168. if (isColumnHeader)
  169. {
  170. //处理第一行数据位列头
  171. lineData[0].Split(this.txt_ColSplit).ToList().ForEach
  172. (
  173. s =>
  174. {
  175. data.Columns.Add(s.Trim());
  176. });
  177. lineData.Remove(lineData[0]);
  178. for (int i = 0; i < lineData.Count; i++)
  179. {
  180. DataRow dr = data.NewRow();
  181. var _s = lineData[i].Split(this.txt_ColSplit);
  182. for (int j = 0; j < _s.Count(); j++)
  183. {
  184. dr[j] = _s[j].ToString();
  185. }
  186. data.Rows.Add(dr);//在表中添加数据
  187. }
  188. }
  189. else
  190. {
  191. //处理第一行数据位列头
  192. for (int i = 0; i < lineData[0].Split(this.txt_ColSplit).ToList().Count; i++)
  193. {
  194. data.Columns.Add("col" + i);
  195. }
  196. for (int i = 0; i < lineData.Count; i++)
  197. {
  198. DataRow dr = data.NewRow();
  199. var _s = lineData[i].Split(this.txt_ColSplit);
  200. for (int j = 0; j < _s.Count(); j++)
  201. {
  202. if (j >= data.Columns.Count)
  203. {
  204. data.Columns.Add("col" + j);
  205. }
  206. dr[j] = _s[j].ToString();
  207. }
  208. data.Rows.Add(dr);//在表中添加数据
  209. }
  210. }
  211. dataTabel = data;
  212. return dataTabel;
  213. }
  214. /// <summary>
  215. /// 解析文本文件导入数据
  216. /// </summary>
  217. /// <param name="txt_RowSplit">行分隔符</param>
  218. /// <param name="txt_ColumnSlit">列分割符</param>
  219. /// <param name="txt_EnCode">编码方式</param>
  220. /// <param name="isColumnHeader">是否显示列头</param>
  221. /// <returns>返回一个DataTable</returns>
  222. public List<DataTable> AnalyzeTxtData(bool multiSelect, char[] txt_RowSplit, char txt_ColumnSlit, string txt_EnCode, bool isColumnHeader = true)
  223. {
  224. List<DataTable> tableList = new List<DataTable>();
  225. m_OpenFlag = true;
  226. //匹配标志
  227. bool flag = false;
  228. //当前行数
  229. int rowCount = 0;
  230. List<string> lineData = new List<string>();
  231. if (txt_RowSplit == null)//分割符
  232. {
  233. return null;
  234. }
  235. if (txt_RowSplit.Length == 0)//行分割符
  236. {
  237. return null;
  238. }
  239. if (string.IsNullOrWhiteSpace(txt_EnCode))//编码方式s
  240. {
  241. return null;
  242. }
  243. OpenFile(multiSelect, out path);
  244. if (!string.IsNullOrEmpty(path))
  245. {
  246. StringReader reader = new StringReader(path);
  247. string tempPath = reader.ReadLine();
  248. while (tempPath != null)
  249. {
  250. if (!File.Exists(tempPath))//文件不存在
  251. {
  252. return null;
  253. }
  254. lineData.Clear();
  255. this.txt_EnCode = Encoding.GetEncoding(txt_EnCode);
  256. //行分割符字符数组,当前只支持最大两个字符的分隔符
  257. char[] tmpStrs = txt_RowSplit;
  258. byte[] lineByte = new byte[tmpStrs.Length];
  259. for (int k = 0; k < tmpStrs.Length; k++)
  260. {
  261. lineByte[k] = Convert.ToByte(Convert.ToInt32(tmpStrs[k]));
  262. }
  263. this.txt_LineSplit = this.txt_EnCode.GetChars(lineByte);
  264. //列分割符
  265. byte[] fieldByte = new byte[1];
  266. char[] fieldSplit = new char[1];
  267. fieldByte[0] = Convert.ToByte(Convert.ToInt32(txt_ColumnSlit));
  268. fieldSplit = this.txt_EnCode.GetChars(fieldByte);
  269. this.txt_ColSplit = fieldSplit[0];
  270. txt_FileStream = new StreamReader(tempPath, this.txt_EnCode, true);
  271. char temp;
  272. StringBuilder rowData = new StringBuilder();
  273. int readCount = 0;
  274. //循环处理所有流数据
  275. while (!txt_FileStream.EndOfStream)
  276. {
  277. //当前处理字符
  278. temp = (char)txt_FileStream.Read();
  279. readCount++;
  280. //当前为第二个字符匹配时执行
  281. if (flag)
  282. {
  283. //匹配不成功
  284. if (temp != this.txt_LineSplit[1])
  285. {
  286. rowData.Append(this.txt_LineSplit[0]);
  287. rowData.Append(temp);
  288. flag = false;
  289. //不是最后一个字符
  290. if (!txt_FileStream.EndOfStream)
  291. {
  292. continue;
  293. }
  294. }
  295. //匹配成功
  296. else
  297. {
  298. flag = false;
  299. }
  300. }
  301. else
  302. {
  303. //第一个字符匹配成功设置匹配成功标志
  304. if (temp == this.txt_LineSplit[0])
  305. {
  306. //两个字符的情况
  307. if (this.txt_LineSplit.Length == 2)
  308. {
  309. flag = true;
  310. //不是最后一个字符
  311. if (!txt_FileStream.EndOfStream)
  312. {
  313. continue;
  314. }
  315. else
  316. {
  317. rowData.Append(temp);
  318. }
  319. }
  320. }
  321. //第一个匹配不成功时按正常数据处理
  322. else
  323. {
  324. rowData.Append(temp);
  325. flag = false;
  326. //不是最后一个字符
  327. if (!txt_FileStream.EndOfStream)
  328. {
  329. if (readCount > 100000)
  330. {
  331. throw new Exception("找到不到指定的行分割符");
  332. }
  333. continue;
  334. }
  335. }
  336. }
  337. lineData.Add(rowData.ToString());
  338. rowData.Clear();
  339. //设置当前行数
  340. rowCount += 1;
  341. //行读取字符个数 清零
  342. readCount = 0;
  343. }
  344. //第一行是否为字段名称
  345. DataTable data = new DataTable("Table_Sheet1");
  346. if (isColumnHeader)
  347. {
  348. //处理第一行数据位列头
  349. lineData[0].Split(this.txt_ColSplit).ToList().ForEach
  350. (
  351. s =>
  352. {
  353. data.Columns.Add(s.Trim());
  354. });
  355. lineData.Remove(lineData[0]);
  356. for (int i = 0; i < lineData.Count; i++)
  357. {
  358. DataRow dr = data.NewRow();
  359. var _s = lineData[i].Split(this.txt_ColSplit);
  360. for (int j = 0; j < _s.Count(); j++)
  361. {
  362. dr[j] = _s[j].ToString();
  363. }
  364. data.Rows.Add(dr);//在表中添加数据
  365. }
  366. }
  367. else
  368. {
  369. //处理第一行数据位列头
  370. for (int i = 0; i < lineData[0].Split(this.txt_ColSplit).ToList().Count; i++)
  371. {
  372. data.Columns.Add("col" + i);
  373. }
  374. for (int i = 0; i < lineData.Count; i++)
  375. {
  376. DataRow dr = data.NewRow();
  377. var _s = lineData[i].Split(this.txt_ColSplit);
  378. for (int j = 0; j < _s.Count(); j++)
  379. {
  380. if (j >= data.Columns.Count)
  381. {
  382. data.Columns.Add("col" + j);
  383. }
  384. dr[j] = _s[j].ToString();
  385. }
  386. data.Rows.Add(dr);//在表中添加数据
  387. }
  388. }
  389. data.TableName = tempPath.Substring(tempPath.LastIndexOf('\\') + 1);
  390. tableList.Add(data);
  391. tempPath = reader.ReadLine();
  392. }
  393. }
  394. return tableList;
  395. }
  396. #region 代付业务解密文件的方法
  397. private const int BUFFER_SIZE = 128 * 1024;
  398. private const ulong FC_TAG = 0xFC010203040506CF;
  399. /// <summary>
  400. ///
  401. /// </summary>
  402. /// <param name="password">密码</param>
  403. /// <param name="salt"></param>
  404. /// <returns>加密对象</returns>
  405. private static SymmetricAlgorithm CreateRijndael(string password, byte[] salt)
  406. {
  407. PasswordDeriveBytes pdb = new PasswordDeriveBytes(password, salt, "SHA256", 1000);
  408. SymmetricAlgorithm sma = Rijndael.Create();
  409. sma.KeySize = 256;
  410. sma.Key = pdb.GetBytes(32);
  411. sma.Padding = PaddingMode.PKCS7;
  412. return sma;
  413. }
  414. /// <summary>
  415. /// 检验两个Byte数组是否相同
  416. /// </summary>
  417. /// <param name="b1">Byte数组</param>
  418. /// <param name="b2">Byte数组</param>
  419. /// <returns>true-相等</returns>
  420. private static bool CheckByteArrays(byte[] b1, byte[] b2)
  421. {
  422. if (b1.Length == b2.Length)
  423. {
  424. for (int i = 0; i < b1.Length; ++i)
  425. {
  426. if (b1[i] != b2[i])
  427. return false;
  428. }
  429. return true;
  430. }
  431. return false;
  432. }
  433. /// <summary>
  434. ///
  435. /// </summary>
  436. /// <param name="filePath"></param>
  437. /// <returns></returns>
  438. private DataSet EcxelToDataSet(string filePath)
  439. {
  440. this.CheckExcelVersion(out excelVerson);//检查Excel版本
  441. this.GetSheets(out listSheet, filePath); //获取Excel的Sheet节点
  442. string connString = ExcelConnString(excelVerson, filePath); //连接字符串
  443. OleDbConnection OleConn = new OleDbConnection(connString); //连接Excel
  444. string sql = " SELECT * FROM [" + listSheet.FirstOrDefault() + "]";
  445. DataSet data = new DataSet();
  446. try
  447. {
  448. //打开连接
  449. OleConn.Open();
  450. //执行查询
  451. OleDbDataAdapter OleDaExcel = new OleDbDataAdapter(sql, OleConn);
  452. OleDaExcel.Fill(data, "Sheet1");
  453. //关闭连接
  454. OleConn.Close();
  455. }
  456. catch (Exception ex)
  457. {
  458. //关闭连接
  459. PlatformLogger.SystemErrorInfo("解析Excel文件发生异常:", ex);
  460. OleConn.Close();
  461. }
  462. return data;
  463. }
  464. /// <summary>
  465. /// 解析加密过的Excel文件
  466. /// </summary>
  467. /// <param name="password"></param>
  468. /// <returns></returns>
  469. public DataTable AnalyseEncryptExcelData(string password, ref string fileID)
  470. {
  471. DataTable dataTable = new DataTable();
  472. this.OpenFile(out path, "Files|*.txt;"); //打开文件提示框
  473. if (string.IsNullOrEmpty(path)) return dataTable;
  474. //去掉前100字节的明文信息
  475. byte[] data = File.ReadAllBytes(path);
  476. string newfile = path.Substring(0, path.Length - 4);
  477. //获取文件唯一ID
  478. byte[] guidB = new byte[32];
  479. Array.Copy(data, 100, guidB, 0, 32);
  480. fileID = Encoding.Default.GetString(guidB);
  481. FileStream foutN = File.OpenWrite(newfile);
  482. foutN.Write(data, 132, data.Length - 132);
  483. foutN.Close();
  484. var outimp = path.Substring(0, path.LastIndexOf(".")) + ".xlsx";
  485. using (FileStream fin = File.OpenRead(newfile), fout = File.OpenWrite(outimp))
  486. {
  487. int size = (int)fin.Length;
  488. byte[] bytes = new byte[BUFFER_SIZE];
  489. int read = -1;
  490. int value = 0;
  491. int outValue = 0;
  492. byte[] IV = new byte[16];
  493. fin.Read(IV, 0, 16);
  494. byte[] salt = new byte[16];
  495. fin.Read(salt, 0, 16);
  496. SymmetricAlgorithm sma = CreateRijndael(password, salt);
  497. sma.IV = IV;
  498. value = 32;
  499. long lSize = -1;
  500. // 创建散列对象, 校验文件
  501. HashAlgorithm hasher = SHA256.Create();
  502. using (CryptoStream cin = new CryptoStream(fin, sma.CreateDecryptor(), CryptoStreamMode.Read),
  503. chash = new CryptoStream(Stream.Null, hasher, CryptoStreamMode.Write))
  504. {
  505. // 读取文件长度
  506. BinaryReader br = new BinaryReader(cin, Encoding.UTF8);
  507. lSize = br.ReadInt64();
  508. ulong tag = br.ReadUInt64();
  509. if (FC_TAG != tag)
  510. return dataTable;
  511. long numReads = lSize / BUFFER_SIZE;
  512. long slack = (long)lSize % BUFFER_SIZE;
  513. for (int i = 0; i < numReads; ++i)
  514. {
  515. read = cin.Read(bytes, 0, bytes.Length);
  516. fout.Write(bytes, 0, read);
  517. chash.Write(bytes, 0, read);
  518. value += read;
  519. outValue += read;
  520. }
  521. if (slack > 0)
  522. {
  523. read = cin.Read(bytes, 0, (int)slack);
  524. fout.Write(bytes, 0, read);
  525. chash.Write(bytes, 0, read);
  526. value += read;
  527. outValue += read;
  528. }
  529. chash.Flush();
  530. chash.Close();
  531. fout.Flush();
  532. fout.Close();
  533. byte[] curHash = hasher.Hash;
  534. // 获取比较和旧的散列对象
  535. byte[] oldHash = new byte[hasher.HashSize / 8];
  536. read = cin.Read(oldHash, 0, oldHash.Length);
  537. if ((oldHash.Length != read) || (!CheckByteArrays(oldHash, curHash)))
  538. return dataTable;
  539. }
  540. if (outValue != lSize)
  541. return dataTable;
  542. }
  543. dataTable = EcxelToDataSet(outimp).Tables[0];
  544. File.Delete(outimp);
  545. //删除表中的所有空行,删除
  546. if (dataTable != null)
  547. {
  548. bool canDel;
  549. for (int i = 0; i < dataTable.Rows.Count; i++)
  550. {
  551. canDel = true;
  552. for (int j = 0; j < dataTable.Columns.Count; j++)
  553. {
  554. if (dataTable.Rows[i][j].ToString().Trim() == string.Empty)
  555. {
  556. }
  557. else
  558. {
  559. canDel = false;
  560. dataTable.Rows[i][j] = dataTable.Rows[i][j].ToString().Replace(" ", "").Replace(" ", "");
  561. }
  562. }
  563. if (canDel)
  564. {
  565. dataTable.Rows[i].Delete();
  566. }
  567. }
  568. dataTable.AcceptChanges();
  569. }
  570. //删除新建文件
  571. File.Delete(newfile);
  572. return dataTable;
  573. }
  574. #endregion
  575. /// <summary>
  576. /// 解析Excel文件导入的数据
  577. /// </summary>
  578. /// <param name="RowCount">可选参数 RowCount=0-默认解析全部行</param>
  579. /// <param name="columnCount">可选参数 ColumnCount=0-默认解析全部列</param>
  580. /// <returns>返回DataTable</returns>
  581. public DataTable AnalyseExcelData(int RowCount = 0, int columnCount = 0)
  582. {
  583. DataTable dataTable = null;
  584. this.OpenFile(out path, "Excel Files|*.xlsx;*.xls;"); //打开文件提示框
  585. this.CheckExcelVersion(out excelVerson);//检查Excel版本
  586. this.GetSheets(out listSheet); //获取Excel的Sheet节点
  587. if (path != null && path.Trim().Length > 0)
  588. {
  589. string connString = ExcelConnString(excelVerson, path); //连接字符串
  590. OleDbConnection OleConn = new OleDbConnection(connString); //连接Excel
  591. string sql = " SELECT * FROM [" + listSheet.FirstOrDefault() + "$]";//查询字符串
  592. DataSet data = new DataSet();
  593. try
  594. {
  595. //打开连接
  596. OleConn.Open();
  597. //执行查询
  598. OleDbDataAdapter OleDaExcel = new OleDbDataAdapter(sql, OleConn);
  599. OleDaExcel.Fill(data, "Sheet1");
  600. dataTable = data.Tables[0];
  601. dataTable.TableName = path.Substring(path.LastIndexOf('\\') + 1);
  602. if (RowCount > 0 && columnCount > 0)
  603. {
  604. DataTable dt = new DataTable(dataTable.TableName);
  605. DataColumnCollection colums = data.Tables[0].Columns;
  606. //处理第一行数据
  607. for (int i = 0; i < columnCount; i++)
  608. {
  609. dt.Columns.Add(colums[i].ToString());
  610. }
  611. for (int i = 0; i < RowCount; i++)
  612. {
  613. DataRow dr = dt.NewRow();
  614. for (int j = 0; j < columnCount; j++)
  615. {
  616. dr[j] = dataTable.Rows[i][j].ToString();
  617. }
  618. dt.Rows.Add(dr);//想表中添加数据
  619. }
  620. dataTable = null;
  621. dataTable = dt;
  622. }
  623. //关闭连接
  624. OleConn.Close();
  625. }
  626. catch (Exception ex)
  627. {
  628. //关闭连接
  629. PlatformLogger.SystemErrorInfo("解析Excel文件发生异常:", ex);
  630. OleConn.Close();
  631. //写错误日志
  632. }
  633. }
  634. //删除表中的所有空行
  635. //if (dataTable != null)
  636. //{
  637. // bool canDel = false;
  638. // for (int i = 0; i < dataTable.Rows.Count; i++)
  639. // {
  640. // for (int j = 0; j < dataTable.Columns.Count; j++)
  641. // {
  642. // if (dataTable.Rows[i][j].ToString() == string.Empty)
  643. // {
  644. // canDel = true;
  645. // }
  646. // else
  647. // {
  648. // canDel = false;
  649. // break;
  650. // }
  651. // }
  652. // if (canDel)
  653. // {
  654. // dataTable.Rows[i].Delete();
  655. // }
  656. // }
  657. // dataTable.AcceptChanges();
  658. //}
  659. //删除表中的所有空行,删除
  660. if (dataTable != null)
  661. {
  662. bool canDel;
  663. for (int i = 0; i < dataTable.Rows.Count; i++)
  664. {
  665. canDel = true;
  666. for (int j = 0; j < dataTable.Columns.Count; j++)
  667. {
  668. if (dataTable.Rows[i][j].ToString().Trim() == string.Empty)
  669. {
  670. }
  671. else
  672. {
  673. canDel = false;
  674. dataTable.Rows[i][j] = dataTable.Rows[i][j].ToString().Replace(" ", "").Replace(" ", "");
  675. }
  676. }
  677. if (canDel)
  678. {
  679. dataTable.Rows[i].Delete();
  680. }
  681. }
  682. dataTable.AcceptChanges();
  683. }
  684. return dataTable;
  685. }
  686. #endregion
  687. #region 私有方法
  688. /// <summary>
  689. /// 取得Excel文件的所有信息
  690. /// </summary>
  691. /// <param name="outSheets">返回所有Sheet信息</param>
  692. private void GetSheets(out List<string> outSheets)
  693. {
  694. //连接字符串
  695. string connString = ExcelConnString(excelVerson, path);
  696. DataTable tableInfo;
  697. List<string> oList = new List<string>();
  698. string tmpstr = "";
  699. try
  700. {
  701. OleDbConnection objConn = new OleDbConnection(connString);
  702. //打开连接
  703. objConn.Open();
  704. tableInfo = objConn.GetSchema("TABLES");
  705. //处理所有SHEET信息
  706. for (int i = 0; i < tableInfo.Rows.Count; i++)
  707. {
  708. tmpstr = tableInfo.Rows[i]["TABLE_NAME"].ToString();
  709. if (tmpstr.LastIndexOf('$') == tmpstr.Length - 1)
  710. {
  711. oList.Add(tmpstr.Trim().TrimEnd('$'));
  712. }
  713. }
  714. //关闭连接
  715. objConn.Close();
  716. }
  717. catch (Exception ex)
  718. {
  719. PlatformLogger.SystemErrorInfo("解析Excel文件发生异常:", ex);
  720. //写错误日志
  721. }
  722. //返回值
  723. outSheets = oList;
  724. }
  725. /// <summary>
  726. /// 取得Excel文件的所有信息
  727. /// </summary>
  728. /// <param name="outSheets">返回所有Sheet信息</param>
  729. private void GetSheets(out List<string> outSheets, string path)
  730. {
  731. //连接字符串
  732. string connString = ExcelConnString(excelVerson, path);
  733. DataTable tableInfo;
  734. List<string> oList = new List<string>();
  735. string tmpstr = "";
  736. try
  737. {
  738. OleDbConnection objConn = new OleDbConnection(connString);
  739. //打开连接
  740. objConn.Open();
  741. tableInfo = objConn.GetSchema("TABLES");
  742. //处理所有SHEET信息
  743. for (int i = 0; i < tableInfo.Rows.Count; i++)
  744. {
  745. tmpstr = tableInfo.Rows[i]["TABLE_NAME"].ToString();
  746. //这种判断方式是错误的,因为sheet页标签的名字很可能是全数字,解析的结果就是数字+$+’
  747. //if (tmpstr.LastIndexOf('$') == tmpstr.Length - 1)
  748. //{
  749. // oList.Add(tmpstr.Trim().TrimEnd('$'));
  750. //}
  751. oList.Add(tmpstr);
  752. }
  753. //关闭连接
  754. objConn.Close();
  755. }
  756. catch (Exception ex)
  757. {
  758. PlatformLogger.SystemErrorInfo("解析Excel文件发生异常:", ex);
  759. //写错误日志
  760. }
  761. //返回值
  762. outSheets = oList;
  763. }
  764. /// <summary>
  765. /// 检查本地Excel版本
  766. /// </summary>
  767. /// <returns>Excel版本号</returns>
  768. private string CheckExcelVersion(out string ExcelVersion)
  769. {
  770. ExcelVersion = string.Empty;
  771. string path03 = string.Empty;
  772. string path07 = string.Empty;
  773. string path10 = string.Empty;
  774. string path13 = string.Empty;
  775. if (Environment.Is64BitOperatingSystem) //64位系统
  776. {
  777. path03 = Get64BitRegistryKey(@"SOFTWARE\\Microsoft\\Office\\11.0\\Excel\\InstallRoot\\", "Path");
  778. if (string.IsNullOrEmpty(path03)) //如果未取到,可能是64系统装的32位office,需取32位注册表
  779. {
  780. path03 = Get32BitRegistryKey(@"SOFTWARE\\Microsoft\\Office\\11.0\\Excel\\InstallRoot\\", "Path");
  781. }
  782. path07 = Get64BitRegistryKey(@"SOFTWARE\\Microsoft\\Office\\12.0\\Excel\\InstallRoot\\", "Path");
  783. if (string.IsNullOrEmpty(path07))//如果未取到,可能是64系统装的32位office,需取32位注册表
  784. {
  785. path07 = Get32BitRegistryKey(@"SOFTWARE\\Microsoft\\Office\\12.0\\Excel\\InstallRoot\\", "Path");
  786. }
  787. path10 = Get64BitRegistryKey(@"SOFTWARE\\Microsoft\\Office\\14.0\\Excel\\InstallRoot\\", "Path");
  788. if (string.IsNullOrEmpty(path10))//如果未取到,可能是64系统装的32位office,需取32位注册表
  789. {
  790. path10 = Get32BitRegistryKey(@"SOFTWARE\\Microsoft\\Office\\14.0\\Excel\\InstallRoot\\", "Path");
  791. }
  792. path13 = Get64BitRegistryKey(@"SOFTWARE\\Microsoft\\Office\\15.0\\Excel\\InstallRoot\\", "Path");
  793. if (string.IsNullOrEmpty(path13))//如果未取到,可能是64系统装的32位office,需取32位注册表
  794. {
  795. path13 = Get32BitRegistryKey(@"SOFTWARE\\Microsoft\\Office\\15.0\\Excel\\InstallRoot\\", "Path");
  796. }
  797. }
  798. else //32位系统
  799. {
  800. path03 = Get32BitRegistryKey(@"SOFTWARE\\Microsoft\\Office\\11.0\\Excel\\InstallRoot\\", "Path");
  801. path07 = Get32BitRegistryKey(@"SOFTWARE\\Microsoft\\Office\\12.0\\Excel\\InstallRoot\\", "Path");
  802. path10 = Get32BitRegistryKey(@"SOFTWARE\\Microsoft\\Office\\14.0\\Excel\\InstallRoot\\", "Path");
  803. path13 = Get32BitRegistryKey(@"SOFTWARE\\Microsoft\\Office\\15.0\\Excel\\InstallRoot\\", "Path");
  804. }
  805. //检查本机是否安装Office2003
  806. if (File.Exists(path03 + "EXCEL.exe"))
  807. {
  808. ExcelVersion = "8.0";
  809. }
  810. //检查本机是否安装Office2007
  811. if (File.Exists(path07 + "EXCEL.exe"))
  812. {
  813. ExcelVersion = "12.0";
  814. }
  815. //检查本机是否安装Office2010
  816. if (File.Exists(path10 + "EXCEL.exe"))
  817. {
  818. ExcelVersion = "12.0";
  819. }
  820. //检查本机是否安装Office2013
  821. if (File.Exists(path13 + "EXCEL.exe"))
  822. {
  823. ExcelVersion = "12.0";
  824. }
  825. //如果在注册表中找不到安装目录,设置初始值
  826. if (string.IsNullOrEmpty(ExcelVersion))
  827. {
  828. ExcelVersion = "12.0";
  829. }
  830. return ExcelVersion;
  831. }
  832. #region 32位程序读取64位系统注册表(HKEY_LOCAL_MACHINE目录)
  833. // 关闭64位(文件系统)的操作转向
  834. [DllImport("Kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
  835. private static extern bool Wow64DisableWow64FsRedirection(ref IntPtr ptr);
  836. // 开启64位(文件系统)的操作转向
  837. [DllImport("Kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
  838. private static extern bool Wow64RevertWow64FsRedirection(IntPtr ptr);
  839. // 获取操作Key值句柄
  840. [DllImport("Advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
  841. private static extern uint RegOpenKeyEx(UIntPtr hKey, string lpSubKey, uint ulOptions,
  842. int samDesired, out IntPtr phkResult);
  843. //关闭注册表转向(禁用特定项的注册表反射)
  844. [DllImport("Advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
  845. private static extern long RegDisableReflectionKey(IntPtr hKey);
  846. //使能注册表转向(开启特定项的注册表反射)
  847. [DllImport("Advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
  848. private static extern long RegEnableReflectionKey(IntPtr hKey);
  849. //获取Key值(即:Key值句柄所标志的Key对象的值)
  850. [DllImport("Advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
  851. private static extern int RegQueryValueEx(IntPtr hKey, string lpValueName, int lpReserved,
  852. out uint lpType, System.Text.StringBuilder lpData,
  853. ref uint lpcbData);
  854. private string Get64BitRegistryKey(string subKeyName, string keyName)
  855. {
  856. int KEY_QUERY_VALUE = (0x0001);
  857. int KEY_WOW64_64KEY = (0x0100);
  858. int KEY_ALL_WOW64 = (KEY_QUERY_VALUE | KEY_WOW64_64KEY);
  859. try
  860. {
  861. //将Windows注册表主键名转化成为不带正负号的整形句柄(与平台是32或者64位有关)
  862. UIntPtr hKey = (UIntPtr)0x80000002;
  863. //声明将要获取Key值的句柄
  864. IntPtr pHKey = IntPtr.Zero;
  865. //记录读取到的Key值
  866. StringBuilder result = new StringBuilder(1024);
  867. uint resultSize = 1024;
  868. uint lpType = 0;
  869. //关闭文件系统转向
  870. IntPtr oldWOW64State = new IntPtr();
  871. if (Wow64DisableWow64FsRedirection(ref oldWOW64State))
  872. {
  873. //获得操作Key值的句柄
  874. RegOpenKeyEx(hKey, subKeyName, 0, KEY_ALL_WOW64, out pHKey);
  875. //关闭注册表转向(禁止特定项的注册表反射)
  876. RegDisableReflectionKey(pHKey);
  877. //获取访问的Key值
  878. RegQueryValueEx(pHKey, keyName, 0, out lpType, result, ref resultSize);
  879. //打开注册表转向(开启特定项的注册表反射)
  880. RegEnableReflectionKey(pHKey);
  881. }
  882. //打开文件系统转向
  883. Wow64RevertWow64FsRedirection(oldWOW64State);
  884. //返回Key值
  885. return result.ToString().Trim();
  886. }
  887. catch (Exception ex)
  888. {
  889. //写错误日志
  890. PlatformLogger.SystemErrorInfo("解析Excel文件发生异常:", ex);
  891. return string.Empty;
  892. }
  893. }
  894. #endregion
  895. #region 32位程序读取32位系统注册表(HKEY_LOCAL_MACHINE目录)
  896. private string Get32BitRegistryKey(string subKeyName, string keyName)
  897. {
  898. string result = string.Empty;
  899. RegistryKey rk = Registry.LocalMachine;
  900. RegistryKey key = rk.OpenSubKey(subKeyName);
  901. if (key != null)
  902. {
  903. result = key.GetValue(keyName).ToString();
  904. }
  905. return result;
  906. }
  907. #endregion
  908. /// <summary>
  909. /// 连接Excel的字符串
  910. /// </summary>
  911. /// <param name="filePath"></param>
  912. /// <returns>连接Excel的字符串</returns>
  913. private string ExcelConnString(string excelVerson, string filePath)
  914. {
  915. string _excelConnString = "";
  916. if (excelVerson == "8.0")
  917. {
  918. _excelConnString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + filePath + ";Extended Properties='Excel 8.0;HDR=Yes'";
  919. }
  920. if (excelVerson == "12.0")
  921. {
  922. _excelConnString = "Provider=Microsoft.Ace.OleDb.12.0;Data Source=" + filePath + ";Extended Properties='Excel 12.0;HDR=Yes'";
  923. }
  924. return _excelConnString;
  925. }
  926. /// <summary>
  927. /// 调用Win32打开提示框,选择文件
  928. /// </summary>
  929. /// <param name="path">返回文件的路径</param>
  930. /// <param name="filter">提示框可选择文件的后缀</param>
  931. private void OpenFile(out string path, string filter = "txt Files|*.txt")
  932. {
  933. path = "";
  934. OpenFileDialog fileDialog = new OpenFileDialog();
  935. fileDialog.Title = "上传文件";
  936. fileDialog.FileName = String.Empty;
  937. fileDialog.Filter = filter;
  938. fileDialog.Multiselect = false;
  939. if (fileDialog.ShowDialog() == true)
  940. {
  941. path = fileDialog.FileName;
  942. }
  943. }
  944. /// <summary>
  945. /// 调用Win32打开提示框,选择文件(支持多选)
  946. /// </summary>
  947. /// <param name="path">返回文件的路径</param>
  948. /// <param name="filter">提示框可选择文件的后缀</param>
  949. private void OpenFile(bool multiSelect, out string path, string filter = "txt Files|*.txt")
  950. {
  951. path = "";
  952. OpenFileDialog fileDialog = new OpenFileDialog();
  953. fileDialog.Title = "上传文件";
  954. fileDialog.FileName = String.Empty;
  955. fileDialog.Filter = filter;
  956. fileDialog.Multiselect = multiSelect;
  957. if (fileDialog.ShowDialog() == true)
  958. {
  959. StringBuilder builder = new StringBuilder();
  960. if (fileDialog.FileNames != null)
  961. {
  962. for (int i = 0; i < fileDialog.FileNames.Length; i++)
  963. {
  964. builder.AppendLine(fileDialog.FileNames[i]);
  965. }
  966. path = builder.ToString();
  967. }
  968. }
  969. }
  970. #endregion
  971. }
  972. }