zoukankan      html  css  js  c++  java
  • C# winform 可视化操作 Excel文件并读取数据

    本人近期接到一个任务,要求开发一个可以操作和读取Excel文件的软件。

    花了几天时间开发完成。本机跑的可以,兼容性还待检测。

    解决方案:

     dsoframer.ocx  + Microsoft.Office.Interop.Excel

    dsoframer.ocx 是用来可视化操作office文件的C#控件,Microsoft.Office.Interop.Excel 是用来操作和读取的控件。

    效果图如下:

    这个是可视化操作,导入excel文件,可以删除行,当然所有的excel操作都可以,已测试wps和Microsoft office 软件都可以正常读取和操作。导入数据是将excel数据读取到DataTable 中。

    第一行和第一列是通过代码添加的,具体实现方式将在下面贴出来。

    DataTable 读取到数据展示如下:

      

    代码部分:

    using System;
    using System.Data;
    using System.Diagnostics;
    using System.IO;
    using System.Reflection;
    using System.Windows.Forms;
    using Microsoft.Office.Interop.Excel;
    using System.Data.OleDb;
    using System.Collections.Generic;
    using System.Text.RegularExpressions;
    
    namespace ReadExcel
    {
        public partial class Form1 : Form
        {
            private AxDSOFramer.AxFramerControl m_axFramerControl = new AxDSOFramer.AxFramerControl();
            System.Data.DataTable dtEnd = new System.Data.DataTable();
            bool isOpenExcel = false;
            public Form1()
            {
                InitializeComponent();
            }
    
    
            #region 按钮事件
            private void button1_Click(object sender, EventArgs e)
            {
                //读取excel
                OpenFileDialog dia = new OpenFileDialog();
                dia.Filter = "公路计价文件(*.xls)|*.xls;*.xlsx";
                dia.FilterIndex = 0;
                dia.ShowDialog();
                if (string.IsNullOrEmpty(dia.FileName))
                {
                    return;
                }
                if (isOpenExcel == true)//先关闭已打开的excel
                {
                    try
                    {
                        CloseFrom();
                    }
                    catch (Exception)
                    {
                    }
                }
    
                //复制到本地 因为快捷方式可以用,修改后可以保存,会导致修改源文件
                string tempFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "TempFile");
                if (!System.IO.Directory.Exists(tempFile)) System.IO.Directory.CreateDirectory(tempFile);
                string tempExcelPath = Path.Combine(tempFile, "tempExcel" + Path.GetExtension(dia.FileName));
                System.IO.File.Copy(dia.FileName, tempExcelPath, true);
    
                try
                {
    
                    //打开本地excel 
                    Init(tempExcelPath);
                    isOpenExcel = true;
    
                    try
                    {
                        //所有的sheet都应该增加
                        object documentExcel = m_axFramerControl.ActiveDocument;
                        //// 获取当前工作薄
                        Workbook workbook = (Microsoft.Office.Interop.Excel.Workbook)documentExcel;
                        foreach (Worksheet worksheet in workbook.Sheets)
                        {
                            if (worksheet != null)
                            {
                                int columnsint = worksheet.UsedRange.Cells.Columns.Count;//得到列数  
                                int rowsint = worksheet.UsedRange.Rows.Count; //得到行数
                                if (rowsint == 1) continue;
                                #region  增加行
                                Range range = (Range)worksheet.Rows[1, Type.Missing];
                                //object   Range.Insert(object   shift,   object   copyorigin);     
                                //shift:   Variant类型,可选。指定单元格的调整方式。可以为下列   XlInsertShiftDirection   常量之一:   
                                //xlShiftToRight   或   xlShiftDown。如果省略该参数,Microsoft   Excel   将根据区域形状确定调整方式。   
                                range.Insert(XlInsertShiftDirection.xlShiftDown, Type.Missing);
    
                                System.Data.DataTable dt = new System.Data.DataTable();
                                dt.Columns.Add("Name");
                                DataRow dr = dt.NewRow();
                                dr[0] = "姓名";
                                dt.Rows.Add(dr);
                                DataRow dr1 = dt.NewRow();
                                dr1[0] = "性别";
                                dt.Rows.Add(dr1);
                                DataRow dr2 = dt.NewRow();
                                dr2[0] = "年龄";
                                dt.Rows.Add(dr2);
                                DataRow dr3 = dt.NewRow();
                                dr3[0] = "地址";
                                dt.Rows.Add(dr3);
                                range = worksheet.get_Range("A1", ToName(columnsint - 1) + "1"); 
                                range.RowHeight = 30;
                                range.Font.Bold = true;
                                string strName = GetNameFromDt(dt);
                                //绑定下拉列表
                                range.Validation.Add(XlDVType.xlValidateList, XlDVAlertStyle.xlValidAlertStop, XlFormatConditionOperator.xlBetween, strName, Type.Missing);//Name就是上面获取的列表
                                // range.Validation.Modify(XlDVType.xlValidateList, XlDVAlertStyle.xlValidAlertStop, Type.Missing, strName, Type.Missing);//单元格已设置数据有效性,只能用代码修改有效性;如果单元格未设置有效性,需要使用 Add 方法
    
                                // 填充值
                                worksheet.Cells[1, 1] = "姓名";
                                worksheet.Cells[1, 2] = "性别";
                                worksheet.Cells[1, 3] = "年龄";
                                worksheet.Cells[1, 4] = "地址";
                                #endregion
    
                                #region 增加列
                                Range xlsColumns = (Range)worksheet.Columns[1, Type.Missing];
                                xlsColumns.Insert(XlInsertShiftDirection.xlShiftToRight, Type.Missing);
    
    
                                System.Data.DataTable dtColumn = new System.Data.DataTable();
                                dtColumn.Columns.Add("Name");
                                DataRow drcol = dtColumn.NewRow();
                                drcol[0] = "有效行";
                                dtColumn.Rows.Add(drcol);
                                DataRow drcol1 = dtColumn.NewRow();
                                drcol1[0] = "无效行";
                                dtColumn.Rows.Add(drcol1);
                                strName = GetNameFromDt(dtColumn);
    
                                //绑定下拉列表
                                //xlsColumns = (Range)worksheet.Columns[1, Type.Missing];
                                xlsColumns = worksheet.get_Range("A2", "A"+ (rowsint+1).ToString());
                                xlsColumns.Validation.Add(XlDVType.xlValidateList, XlDVAlertStyle.xlValidAlertStop, XlFormatConditionOperator.xlBetween, strName, Type.Missing);//Name就是上面获取的列表
                                xlsColumns.ColumnWidth = 20;
                                // 填充值
                                xlsColumns.Value = "有效行";
                                #endregion
                                Range m_objRange = worksheet.get_Range("A1", Type.Missing);
                                m_objRange.Borders[XlBordersIndex.xlDiagonalDown].ColorIndex = XlColorIndex.xlColorIndexAutomatic;
                                m_objRange.Value = "           识别行
      设置列";
                            }
                        }
    
    
                    }
                    catch (Exception ex)
                    {
    
                        throw;
                    }
    
                }
                catch (Exception ex)
                {
                    MessageBox.Show("打开失败!" + ex.ToString());
                }
            }
    
            /// <summary>
            /// 读取쫽뻝
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void button2_Click(object sender, EventArgs e)
            {
                if (!isOpenExcel)
                {
                    MessageBox.Show("未导入Excel文件!");
                    return;
                }
                object documentExcel = m_axFramerControl.ActiveDocument;
    
                #region 保存本地读取方法 存在的问题是多个sheet 不知道读取哪个,下面的方法可以读取当前活动页
                ////另存为excel
                //string filePath = "F:\111.xls";
                //m_axFramerControl.SaveAs(filePath, true);//另存为xls       
    
                ////读取excel 到datatable
                //System.Data.DataTable dt = GetDataFromExcel(filePath);
                #endregion
    
                try
                {
                    //先保存本地,不然在修改中的单元格依然读取的是原数据
                    m_axFramerControl.SaveAs(m_axFramerControl.DocumentFullName, true);//另存为xls  
    
    
                    //// 获取当前工作薄
                    Workbook workbook = (Microsoft.Office.Interop.Excel.Workbook)documentExcel;
                    Worksheet worksheet = (Microsoft.Office.Interop.Excel.Worksheet)workbook.ActiveSheet;
    
                    if (worksheet != null)
                    { // 取得总记录行数(包括标题列)
                        int rowsint = worksheet.UsedRange.Rows.Count; //得到行数
                        int columnsint = worksheet.UsedRange.Cells.Columns.Count;//得到列数
                        //取得数据范围区域 (标题列) 
                        Range rng1 = worksheet.Cells.get_Range("A1", ToName(columnsint - 1) + "1");   //item
                        object[,] arryItem = (object[,])rng1.Value2;
                        string[] tmp = new string[columnsint];
                        for (int i = 0; i < columnsint; i++)
                        {
                            if (arryItem[1, i + 1] == null)
                                continue;
                            tmp[i] = arryItem[1, i + 1].ToString();
                        }
    
                        Range mRange = worksheet.get_Range("A2", ToName(columnsint - 1) + rowsint);
    
                        object[,] mArray = (object[,])mRange.Formula;
                        string[,] myStrArr = new string[rowsint - 1, columnsint];
                        for (int i = 0; i < rowsint - 1; i++)
                        {
                            for (int j = 0; j < columnsint; j++)
                            {
                                myStrArr[i, j] = mArray[i + 1, j + 1].ToString();
                            }
                        }
    
                        dtEnd = ConvertToDataTable(tmp, myStrArr);
                        MessageBox.Show("读取成功!");
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show("读取失败!" + ex.ToString());
                }
    
    
            }
            private void btn_deleteRow_Click(object sender, EventArgs e)
            {
                if (!isOpenExcel)
                {
                    MessageBox.Show("未导入Excel文件!");
                    return;
                }
                //先保存本地,不然在修改中的单元格依然读取的是原数据
                m_axFramerControl.SaveAs(m_axFramerControl.DocumentFullName, true);//另存为xls  
    
                object documentExcel = m_axFramerControl.ActiveDocument;
    
                Range excelRange = GetSelectionCell(documentExcel);
                if (excelRange == null)
                {
                    MessageBox.Show("未选择单元格或行!");
                    return;
                }
                excelRange.Select();
                excelRange.EntireRow.Delete(XlDeleteShiftDirection.xlShiftUp);
    
            }
    
            /// <summary>
            /// 显示数据
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void button3_Click(object sender, EventArgs e)
            {
                Form2 frm = new Form2(this.dtEnd);
                frm.ShowDialog();
    
            }
            #endregion
    
    
            #region AxFramerControl Excel 的加载
    
            //总的加载Excel方法
            private void Init(string _ExcelFilePath)
            {
                try
                {
                    RegControl();
    
                    if (!File.Exists(_ExcelFilePath))
                    {
                        MessageBox.Show("文件不存在或未标识的文件格式!", "提示信息");
                        return;
                        //throw new ApplicationException("文件不存在或未标识的文件格式!");
                    }
    
                    AddAxFramerControl();//加载填充控件
                    m_axFramerControl.Titlebar = false;//是否显示excel标题栏
                    m_axFramerControl.Menubar = false;//是否显示excel的菜单栏
                    m_axFramerControl.Toolbars = false;//是否显示excel的工具栏
    
                    InitOfficeControl(_ExcelFilePath);
                }
                catch (Exception ex)
                {
                    throw ex;
                }
    
            }
    
            //第二步:向panel填充AxFramerControl控件
            private void AddAxFramerControl()
            {
                try
                {
                    this.panel1.Controls.Add(m_axFramerControl);
                    m_axFramerControl.Dock = DockStyle.Fill;
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                    throw;
                }
    
            }
    
            //第一步:注册AxFramerControl
            public bool RegControl()
            {
                try
                {
                    Assembly thisExe = Assembly.GetExecutingAssembly();
                    System.IO.Stream myS = thisExe.GetManifestResourceStream("NameSpaceName.dsoframer.ocx");
    
                    string sPath = System.AppDomain.CurrentDomain.BaseDirectory + @"dsoframer.ocx";
                    ProcessStartInfo psi = new ProcessStartInfo("regsvr32", "/s " + sPath);
                    Process.Start(psi);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
                return true;
            }
    
            //下面这个方法是dso打开文件时需要的一个参数,代表office文件类型
            /// <summary>
            /// 根据后缀名得到打开方式
            /// </summary>
            /// <param name="_sExten"></param>
            /// <returns></returns>
            private string LoadOpenFileType(string _sExten)
            {
                try
                {
                    string sOpenType = "";
                    switch (_sExten.ToLower())
                    {
                        case "xls":
                        case "xlsx":
                            sOpenType = "Excel.Sheet";
                            break;
                        case "doc":
                        case "docx":
                            sOpenType = "Word.Document";
                            break;
                        case "ppt":
                            sOpenType = "PowerPoint.Show";
                            break;
                        case "vsd":
                        case "vsdx":
                            sOpenType = "Visio.Drawing";
                            break;
                        default:
                            sOpenType = "Word.Document";
                            break;
                    }
                    return sOpenType;
    
                }
                catch (Exception ex)
                {
                    throw ex;
                }
            }
    
            /// <summary>
            /// 第三步:初始化office控件,加载Excel
            /// </summary>
            /// <param name="_sFilePath">本地文档路径</param>
            private void InitOfficeControl(string _sFilePath)
            {
                try
                {
                    if (m_axFramerControl == null)
                    {
                        throw new ApplicationException("请先初始化office控件对象!");
                    }
    
                    //this.m_axFramerControl.SetMenuDisplay(48);
                    //这个方法很特别,一个组合菜单控制方法,我还没有找到参数的规律,有兴趣的朋友可以研究一下
                    string sExt = System.IO.Path.GetExtension(_sFilePath).Replace(".", "");
                    //this.m_axFramerControl.CreateNew(this.LoadOpenFileType(sExt));//创建新的文件
                    this.m_axFramerControl.Open(_sFilePath, false, this.LoadOpenFileType(sExt), "", "");//打开文件
                    //隐藏标题
                    this.m_axFramerControl.Titlebar = false;
                }
                catch (Exception ex)
                {
                    throw ex;
                }
            }
    
            /// <summary>
            /// 关闭当前界面
            /// </summary>
            public void CloseFrom()
            {
                try
                {
                    if (this.m_axFramerControl != null)
                    {
                        this.m_axFramerControl.Close();
                    }
                }
                catch (Exception ex)
                {
                    throw ex;
                }
            }
    
            private void Form1_FormClosing(object sender, FormClosingEventArgs e)
            {
                try
                {
                    CloseFrom();
                }
                catch (Exception)
                {
                }
            }
            #endregion
    
    
            #region 方法
            // 获得当前窗体
            Window GetActiveWindow(object Document)
            {
                if (Document == null)
                {
                    return null;
                }
    
                Workbook workbook = null;
                Worksheet worksheet = null;
                try
                {
                    //// 获取当前工作薄
                    workbook = (Microsoft.Office.Interop.Excel.Workbook)Document;
                    //// 获取当前工作页
                    worksheet = (Microsoft.Office.Interop.Excel.Worksheet)workbook.ActiveSheet;
                    Window window = null;
    
                    if (worksheet != null)
                    {
                        //// 获取当前活动窗口
                        window = worksheet.Application.ActiveWindow;
                    }
    
                    return window;
                }
                catch
                {
                    return null;
                }
            }
            Range GetSelectionCell(object Document)
            {
                if (Document == null)
                {
                    return null;
                }
    
                Workbook workbook = null;
                Worksheet worksheet = null;
                try
                {
                    workbook = (Microsoft.Office.Interop.Excel.Workbook)Document;
                    worksheet = (Microsoft.Office.Interop.Excel.Worksheet)workbook.ActiveSheet;
                    Range range = null;
    
                    if (worksheet != null)
                    {
                        //// 获取所选区域的第一次选中的单元格
                        range = worksheet.Application.ActiveCell;
                    }
    
                    return range;
                }
                catch
                {
                    return null;
                }
    
            }
    
            public System.Data.DataTable GetDataFromExcel(string filePath)
    
            {
                string connStr = "";
    
    
                string fileType = System.IO.Path.GetExtension(filePath);
                if (string.IsNullOrEmpty(fileType)) return null;
                if (fileType == ".xls")
                    connStr = "Provider=Microsoft.Jet.OLEDB.4.0;" + "Data Source=" + filePath + ";" + ";Extended Properties="Excel 8.0;HDR=NO;IMEX=1"";
                else
                    connStr = "Provider=Microsoft.ACE.OLEDB.12.0;" + "Data Source=" + filePath + ";" + ";Extended Properties="Excel 12.0;HDR=NO;IMEX=1"";
                string sql_F = "Select * FROM [{0}]  ";
                OleDbConnection conn = null;
                OleDbDataAdapter da = null;
                System.Data.DataTable dataTable = new System.Data.DataTable();
                try
                {
                    // 初始化连接,并打开                    
                    conn = new OleDbConnection(connStr);
                    conn.Open();
                    da = new OleDbDataAdapter();
                    da.SelectCommand = new OleDbCommand(String.Format(sql_F, "Sheet1$"), conn);
                    da.Fill(dataTable);
                }
                catch (Exception ex)
                {
    
    
                }
                finally
                {                  // 关闭连接                    
                    if (conn.State == ConnectionState.Open)
                    {
                        conn.Close();
                        da.Dispose();
                        conn.Dispose();
                    }
                }
                conn.Close();
                da.Dispose();
                conn.Dispose();
                return dataTable;
            }
    
            #region - 由数字转换为Excel中的列字母 -
    
            public int ToIndex(string columnName)
            {
                if (!Regex.IsMatch(columnName.ToUpper(), @"[A-Z]+")) { throw new Exception("invalid parameter"); }
    
                int index = 0;
                char[] chars = columnName.ToUpper().ToCharArray();
                for (int i = 0; i < chars.Length; i++)
                {
                    index += ((int)chars[i] - (int)'A' + 1) * (int)Math.Pow(26, chars.Length - i - 1);
                }
                return index - 1;
            }
    
    
            public string ToName(int index)
            {
                if (index < 0) { throw new Exception("invalid parameter"); }
    
                List<string> chars = new List<string>();
                do
                {
                    if (chars.Count > 0) index--;
                    chars.Insert(0, ((char)(index % 26 + (int)'A')).ToString());
                    index = (int)((index - index % 26) / 26);
                } while (index > 0);
    
                return String.Join(string.Empty, chars.ToArray());
            }
            #endregion
    
    
            /// <summary>  
            /// 反一个M行N列的二维数组转换为DataTable  
            /// </summary>  
            /// <param name="ColumnNames">一维数组,代表列名,不能有重复值</param>  
            /// <param name="Arrays">M行N列的二维数组</param>  
            /// <returns>返回DataTable</returns>  
            /// <remarks>柳永法 http://www.yongfa365.com/ </remarks>  
            public static System.Data.DataTable ConvertToDataTable(string[] ColumnNames, string[,] Arrays)
            {
                System.Data.DataTable dt = new System.Data.DataTable();
    
                foreach (string ColumnName in ColumnNames)
                {
                    dt.Columns.Add(ColumnName, typeof(string));
                }
    
                for (int i1 = 0; i1 < Arrays.GetLength(0); i1++)
                {
                    DataRow dr = dt.NewRow();
                    bool isData = false;
                    for (int i = 0; i < ColumnNames.Length; i++)
                    {
                        if (Arrays[i1, i] != null)
                        {
                            isData = true;
                            dr[i] = Arrays[i1, i].ToString();
                        }
                    }
                    if (isData)
                        dt.Rows.Add(dr);
                }
    
                return dt;
    
            }
    
            private string GetNameFromDt(System.Data.DataTable dt)
            {
                string str = "";
                foreach (DataRow dr in dt.Rows)
                {
                    str += dr["Name"].ToString() + ",";
                }
                return str.TrimEnd(',');
            }
            #endregion
    
    
        }
    }
  • 相关阅读:
    钱多多软件制作04
    团队项目01应用场景
    HDU 4411 arrest
    HDU 4406 GPA
    HDU 3315 My Brute
    HDU 3667 Transportation
    HDU 2676 Matrix
    欧拉回路三水题 POJ 1041 POJ 2230 POJ 1386
    SPOJ 371 BOXES
    POJ 3422 Kaka's Matrix Travels
  • 原文地址:https://www.cnblogs.com/shengkai/p/9647075.html
Copyright © 2011-2022 走看看