C#读写文件:csv,xls,.xlsx文件 (同时读取多个相同结构 的文件) 更新中2019.1.23

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;
using System.Data.OleDb;
using System.Data.SqlClient;
using System.IO;
using System.Windows.Forms;

namespace AliWorkbenchProgram
{
    public class ClassSimbaRptOp
    {
        public static string message = "";
        public static string writeMessage = "";


        public static DataTable OpenCSV(string filePath)//从csv读取数据返回table
        {
            System.Text.Encoding encoding = GetType(filePath); //Encoding.ASCII;//
            DataTable dt = new DataTable();
            System.IO.FileStream fs = new System.IO.FileStream(filePath, System.IO.FileMode.Open,System.IO.FileAccess.Read);

            System.IO.StreamReader sr = new System.IO.StreamReader(fs, encoding);

            //记录每次读取的一行记录
            string strLine = "";
            //记录每行记录中的各字段内容
            string[] aryLine = null;
            string[] tableHead = null;
            //标示列数
            int columnCount = 0;
            //标示是否是读取的第一行
            bool IsFirst = true;
            //逐行读取CSV中的数据
            while ((strLine = sr.ReadLine()) != null)
            {
                if (IsFirst == true)
                {
                    tableHead = strLine.Split(',');
                    IsFirst = false;
                    columnCount = tableHead.Length;
                    //创建列
                    for (int i = 0; i < columnCount; i++)
                    {
                        DataColumn dc = new DataColumn(tableHead[i]);
                        dt.Columns.Add(dc);
                    }
                }
                else
                {
                    aryLine = strLine.Split(',');
                    DataRow dr = dt.NewRow();
                    for (int j = 0; j < columnCount; j++)
                    {
                        dr[j] = aryLine[j];
                    }
                    dt.Rows.Add(dr);
                }
            }
            if (aryLine != null && aryLine.Length > 0)
            {
                dt.DefaultView.Sort = tableHead[0] + " " + "asc";
            }

            sr.Close();
            fs.Close();
            return dt;
        }
        /// 给定文件的路径,读取文件的二进制数据,判断文件的编码类型
        /// <param name="FILE_NAME">文件路径</param>
        /// <returns>文件的编码类型</returns>

        public static System.Text.Encoding GetType(string FILE_NAME)
        {
            System.IO.FileStream fs = new System.IO.FileStream(FILE_NAME, System.IO.FileMode.Open,
                System.IO.FileAccess.Read);
            System.Text.Encoding r = GetType(fs);
            fs.Close();
            return r;
        }

        /// 通过给定的文件流,判断文件的编码类型
        /// <param name="fs">文件流</param>
        /// <returns>文件的编码类型</returns>
        public static System.Text.Encoding GetType(System.IO.FileStream fs)
        {
            byte[] Unicode = new byte[] { 0xFF, 0xFE, 0x41 };
            byte[] UnicodeBIG = new byte[] { 0xFE, 0xFF, 0x00 };
            byte[] UTF8 = new byte[] { 0xEF, 0xBB, 0xBF }; //带BOM
            System.Text.Encoding reVal = System.Text.Encoding.Default;

            System.IO.BinaryReader r = new System.IO.BinaryReader(fs, System.Text.Encoding.Default);
            int i;
            int.TryParse(fs.Length.ToString(), out i);
            byte[] ss = r.ReadBytes(i);
            if (IsUTF8Bytes(ss) || (ss[0] == 0xEF && ss[1] == 0xBB && ss[2] == 0xBF))
            {
                reVal = System.Text.Encoding.UTF8;
            }
            else if (ss[0] == 0xFE && ss[1] == 0xFF && ss[2] == 0x00)
            {
                reVal = System.Text.Encoding.BigEndianUnicode;
            }
            else if (ss[0] == 0xFF && ss[1] == 0xFE && ss[2] == 0x41)
            {
                reVal = System.Text.Encoding.Unicode;
            }
            r.Close();
            return reVal;
        }

        /// 判断是否是不带 BOM 的 UTF8 格式
        /// <param name="data"></param>
        /// <returns></returns>
        private static bool IsUTF8Bytes(byte[] data)
        {
            int charByteCounter = 1;  //计算当前正分析的字符应还有的字节数
            byte curByte; //当前分析的字节.
            for (int i = 0; i < data.Length; i++)
            {
                curByte = data[i];
                if (charByteCounter == 1)
                {
                    if (curByte >= 0x80)
                    {
                        //判断当前
                        while (((curByte <<= 1) & 0x80) != 0)
                        {
                            charByteCounter++;
                        }
                        //标记位首位若为非0 则至少以2个1开始 如:110XXXXX...........1111110X 
                        if (charByteCounter == 1 || charByteCounter > 6)
                        {
                            return false;
                        }
                    }
                }
                else
                {
                    //若是UTF-8 此时第一位必须为1
                    if ((curByte & 0xC0) != 0x80)
                    {
                        return false;
                    }
                    charByteCounter--;
                }
            }
            if (charByteCounter > 1)
            {
                throw new Exception("非预期的byte格式");
            }
            return true;

        }








        public void ExportToSvc(DataTable dt)
        {

            string saveFileName = ""; //获取文件名,不带路径   
            string saveFileDirectory = "";//获得文件路径   
            string saveFilePath = ""; //文件路径和文件名和扩展名
            string exportFileTime = DateTime.Now.ToString("yyyyMMddHHmmss");
            string exportFileName = "Export" + exportFileTime;

            SaveFileDialog saveFileDialog = new SaveFileDialog();
            saveFileDialog.InitialDirectory = @"C:\Users\Administrator\Desktop\";   //@是取消转义字符的意思  
            saveFileDialog.FileName = saveFileDialog.InitialDirectory + exportFileName + ".csv";
            saveFileDialog.Filter = "(*.CSV)|*.csv";//设置文件类型   
            saveFileDialog.FilterIndex = 0;//设置默认文件类型显示顺序(可以不设置)
            saveFileDialog.RestoreDirectory = true;//保存对话框是否记忆上次打开的目录
            saveFileDialog.CreatePrompt = true;
            saveFileDialog.Title = "导出csv文件保存路径";

            DialogResult dialogResult = saveFileDialog.ShowDialog();
            message += "=== 本次( 时间:" + exportFileTime + " )导出日志" + "\r\n" ;
            if (dialogResult == DialogResult.OK)
            {
                
                saveFilePath = saveFileDialog.FileName;//获得文件路径     
                saveFileName = saveFilePath.Substring(saveFilePath.LastIndexOf("\\") + 1);
                saveFileDirectory = saveFilePath.Substring(0, saveFilePath.LastIndexOf("\\")); //获取文件路径,不带文件名  

                message += "已选择导出文件路径: " + saveFilePath + "\r\n";
                message += "已命名导出文件名: " + saveFileName+ "\r\n";

                try
                {
                    if (saveFilePath.Length != 0)
                    {
                        //没有数据的话就不往下执行   
                        if (dt.Rows.Count == 0)
                        {
                            message += "已选导出无数据"+ "\r\n\r\n";
                            return;
                        }
                        /*
                        if (File.Exists(saveFilePath))
                        {
                            File.Delete(saveFilePath);
                        }
                        */
                        //先打印标头
                        StringBuilder strColu = new StringBuilder();
                        StringBuilder strValue = new StringBuilder();
                        int i = 0;

                        StreamWriter sw = new StreamWriter(new FileStream(saveFilePath, FileMode.CreateNew), Encoding.GetEncoding("GB2312"));
                        for (i = 0; i <= dt.Columns.Count - 1; i++)
                        {
                            strColu.Append(dt.Columns[i].ColumnName);
                            strColu.Append(",");
                        }

                        strColu.Remove(strColu.Length - 1, 1);//移出掉最后一个,字符
                        sw.WriteLine(strColu);

                        message += "成功导出:标题列数 " + dt.Columns.Count.ToString ()+" 列";

                        foreach (DataRow dr in dt.Rows)
                        {
                            strValue.Remove(0, strValue.Length);//移出

                            for (i = 0; i <= dt.Columns.Count - 1; i++)
                            {
                                strValue.Append(dr[i].ToString());
                                strValue.Append(",");
                            }
                            strValue.Remove(strValue.Length - 1, 1);//移出掉最后一个,字符
                            sw.WriteLine(strValue);
                        }
                        message += ",行数 "+ dt.Rows.Count .ToString ()+" 行" + "\r\n\r\n";
                        sw.Close();
                    }
                }
                catch (Exception ex)
                {
                    message += "导出失败:" + ex.Message+ "\r\n\r\n";
                    // Console.WriteLine("导出失败" + ex.Message, "提示");
                }
                // System.Diagnostics.Process.Start(strPath);
            }
            if(dialogResult == DialogResult.Cancel)
            {
                message += "导出失败:已人为取消导出 " + "\r\n\r\n";
            }


        }




        public DataSet LoadExcelToDataset()
        {
            OleDbConnection conn = null;
            OleDbDataAdapter da = null;
            DataSet ds = null;
            DataTable dtSheetName = null;
            string exportFileTime = DateTime.Now.ToString("yyyyMMddHHmmss");

            OpenFileDialog dlg = new OpenFileDialog();
            dlg.Multiselect = true;//允许同时选择多个文件 
            dlg.InitialDirectory = @"C:\Users\Administrator\Desktop\";
            dlg.Filter = "xls files(*.xls)|*.xls|xlsx files(*.xlsx)|*.xlsx";
            dlg.FilterIndex = 1;
            dlg.RestoreDirectory = true;


            DialogResult dialogResult = dlg.ShowDialog();
            message += "=== 本次( 时间:" + exportFileTime + " )读取日志" + "\r\n"; ;
            if (dialogResult == DialogResult.OK)
                {
                try
                {
                    ds = new DataSet();
                    message +="【已选准备读取的文件数:" + dlg.FileNames.Length.ToString() + " 个】"+ "\r\n";
                    int intFileCount = 0;
                    foreach (string strFileName in dlg.FileNames)
                    {
                        string fileExtension = System.IO.Path.GetExtension(strFileName);//扩展名 ".xls"
                        string strConn = "";

                       
                        if (fileExtension == ".xls")
                        {
                            strConn = "Provider=Microsoft.Jet.OLEDB.4.0;" + "Data Source=" + strFileName + ";" + ";Extended Properties=\"Excel 8.0;HDR=YES;IMEX=1\"";
                        }
                        if (fileExtension == ".xlsx")
                        {
                            strConn = "Provider=Microsoft.ACE.OLEDB.12.0;" + "Data Source=" + strFileName + ";" + ";Extended Properties=\"Excel 12.0;HDR=YES;IMEX=1\"";
                        }

                        // 初始化连接,并打开
                        conn = new OleDbConnection(strConn);
                        conn.Open();

                        dtSheetName = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, new object[] { null, null, null, "TABLE" });
                        intFileCount += 1;
                        da = new OleDbDataAdapter();// 初始化适配器
                        message +=  "--已读取第 "+intFileCount .ToString ()+" 个文件,路径: " + strFileName + "\r\n" + "  文件扩展名:" + fileExtension+"\r\n";
                        message += "  SheetName数:" + dtSheetName.Rows.Count.ToString() + " 个"+"\r\n";

                        for (int i = 0; i < dtSheetName.Rows.Count; i++)
                        {
                            string SheetName = (string)dtSheetName.Rows[i]["TABLE_NAME"];

                            if (SheetName.Contains("$") && !SheetName.Replace("'", "").EndsWith("$"))
                            {
                                continue;
                            }

                            da.SelectCommand = new OleDbCommand(String.Format("Select * FROM [{0}]", SheetName), conn);
                            DataSet dsItem = new DataSet();
                            da.Fill(dsItem, SheetName);
                            ds.Tables.Add(dsItem.Tables[SheetName].Copy());

                            message += "  SheetName名: " + SheetName+ "\r\n";
                            message += "  已读取列数:" + dsItem.Tables[SheetName].Columns.Count.ToString() + " 列";
                            message += " ,已读取行数:" + dsItem.Tables[SheetName].Rows.Count.ToString() + " 行"+ "\r\n";
                        }
                        conn.Close();
                    }
                    message += "\r\n" + "<<< 已读需要-合并总表格数: " + ds.Tables.Count.ToString() + " 个 >>>" + "\r\n";





                }
                catch (Exception e)
                {
                         MessageBox.Show("Excel表格读取失败,额外信息:" + e.Message);
                         //throw;
                }
                finally
                {
                        // 关闭连接
                     if (conn.State == ConnectionState.Open)
                     {
                       conn.Close();
                       da.Dispose();
                       conn.Dispose();
                     }
            }
            if (dialogResult == DialogResult.OK)
            {
                    message += "本次读取:已人为取消" + "\r\n";
            }


        }

            return ds;
        }


        public DataTable GetAllDataTable(DataSet ds)
        {
            DataTable newDataTable = null;
            try
            {
                newDataTable = ds.Tables[0].Clone();                //创建新表 克隆以有表的架构。
                object[] objArray = new object[newDataTable.Columns.Count];   //定义与表列数相同的对象数组 存放表的一行的值。
                int intException = 0;
                int intAdd = 0;
                for (int i = 0; i < ds.Tables.Count; i++)
                {
                    intException = i;
                    try
                    {
                        for (int j = 0; j < ds.Tables[i].Rows.Count; j++)
                        {
                            ds.Tables[i].Rows[j].ItemArray.CopyTo(objArray, 0);    //将表的一行的值存放数组中。
                            newDataTable.Rows.Add(objArray);                       //将数组的值添加到新表中。 
                        }
                        intAdd += 1;
                        message += "合并成功:第 " + (i + 1).ToString() + " 张表, 表名: " + ds.Tables[i].TableName + ",完成合并列数: " + ds.Tables[i].Columns.Count.ToString() + " 列" + " ,行数: " + ds.Tables[i].Rows.Count.ToString() + " 行" + "\r\n";
                    }
                    catch (Exception e)
                    {
                        message += "--->合并失败: 第" + (intException + 1).ToString() + "张表, 表名: " + ds.Tables[intException].TableName + " ,待合并列数: " + ds.Tables[intException].Columns.Count.ToString() + " 列" + "与已合并表列数 " + newDataTable.Columns.Count.ToString() + " 不等 【 仅支持合并多个结构相同的excel文件" + "\r\n";
                        //MessageBox.Show("Excel表格读取失败,额外信息:" + e.Message);
                        //throw;
                    }
                    continue;//跳过本次循环未执行的代码,继续执行下一次循环

                }

                message += "本次成功合并表数:" + intAdd.ToString() + ",行数: " + newDataTable.Rows.Count.ToString() + " 行" + "\r\n\r\n";

                                                        //返回新表。
            }
            catch (Exception e)
            {
                message += "本次读取:已人为取消" + "\r\n\r\n";
            }
            return newDataTable;
        }








    }
}

猜你喜欢

转载自blog.csdn.net/zgscwxd/article/details/86614821