投机在用的Excel操作类,因为时常在工作中要操作Excel文件,不过使用vba达成起来其实是不方便人民群众,而且编写也很不方便,拼接三个字符串都看的头昏眼花。

C# 导出 Excel 的各样格局总计,

第一种:使用 Microsoft.Office.Interop.Excel.dll

率先要求设置 office 的
excel,然后再找到 Microsoft.Office.Interop.Excel.dll 组件,添加到引用。

金沙注册送58 1

金沙注册送58 2

public void ExportExcel(DataTable dt)
        {
            if (dt != null)
            {
                Microsoft.Office.Interop.Excel.Application excel = new Microsoft.Office.Interop.Excel.Application();

                if (excel == null)
                {
                    return;
                }

                //设置为不可见,操作在后台执行,为 true 的话会打开 Excel
                excel.Visible = false;

                //打开时设置为全屏显式
                //excel.DisplayFullScreen = true;

                //初始化工作簿
                Microsoft.Office.Interop.Excel.Workbooks workbooks = excel.Workbooks;

                //新增加一个工作簿,Add()方法也可以直接传入参数 true
                Microsoft.Office.Interop.Excel.Workbook workbook = workbooks.Add(Microsoft.Office.Interop.Excel.XlWBATemplate.xlWBATWorksheet);
                //同样是新增一个工作簿,但是会弹出保存对话框
                //Microsoft.Office.Interop.Excel.Workbook workbook = excel.Application.Workbooks.Add(true);

                //新增加一个 Excel 表(sheet)
                Microsoft.Office.Interop.Excel.Worksheet worksheet = (Microsoft.Office.Interop.Excel.Worksheet)workbook.Worksheets[1];

                //设置表的名称
                worksheet.Name = dt.TableName;
                try
                {
                    //创建一个单元格
                    Microsoft.Office.Interop.Excel.Range range;

                    int rowIndex = 1;       //行的起始下标为 1
                    int colIndex = 1;       //列的起始下标为 1

                    //设置列名
                    for (int i = 0; i < dt.Columns.Count; i++)
                    {
                        //设置第一行,即列名
                        worksheet.Cells[rowIndex, colIndex + i] = dt.Columns[i].ColumnName;

                        //获取第一行的每个单元格
                        range = worksheet.Cells[rowIndex, colIndex + i];

                        //设置单元格的内部颜色
                        range.Interior.ColorIndex = 33;

                        //字体加粗
                        range.Font.Bold = true;

                        //设置为黑色
                        range.Font.Color = 0;

                        //设置为宋体
                        range.Font.Name = "Arial";

                        //设置字体大小
                        range.Font.Size = 12;

                        //水平居中
                        range.HorizontalAlignment = Microsoft.Office.Interop.Excel.XlHAlign.xlHAlignCenter;

                        //垂直居中
                        range.VerticalAlignment = Microsoft.Office.Interop.Excel.XlVAlign.xlVAlignCenter;
                    }

                    //跳过第一行,第一行写入了列名
                    rowIndex++;

                    //写入数据
                    for (int i = 0; i < dt.Rows.Count; i++)
                    {
                        for (int j = 0; j < dt.Columns.Count; j++)
                        {
                            worksheet.Cells[rowIndex + i, colIndex + j] = dt.Rows[i][j].ToString();
                        }
                    }

                    //设置所有列宽为自动列宽
                    //worksheet.Columns.AutoFit();

                    //设置所有单元格列宽为自动列宽
                    worksheet.Cells.Columns.AutoFit();
                    //worksheet.Cells.EntireColumn.AutoFit();

                    //是否提示,如果想删除某个sheet页,首先要将此项设为fasle。
                    excel.DisplayAlerts = false;

                    //保存写入的数据,这里还没有保存到磁盘
                    workbook.Saved = true;

                    //设置导出文件路径
                    string path = HttpContext.Current.Server.MapPath("Export/");

                    //设置新建文件路径及名称
                    string savePath = path + DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss") + ".xlsx";

                    //创建文件
                    FileStream file = new FileStream(savePath, FileMode.CreateNew);

                    //关闭释放流,不然没办法写入数据
                    file.Close();
                    file.Dispose();

                    //保存到指定的路径
                    workbook.SaveCopyAs(savePath);

                    //还可以加入以下方法输出到浏览器下载
                    FileInfo fileInfo = new FileInfo(savePath);
                    OutputClient(fileInfo);
                }
                catch(Exception ex)
                {

                }
                finally
                {
                    workbook.Close(false, Type.Missing, Type.Missing);
                    workbooks.Close();

                    //关闭退出
                    excel.Quit();

                    //释放 COM 对象
                    Marshal.ReleaseComObject(worksheet);
                    Marshal.ReleaseComObject(workbook);
                    Marshal.ReleaseComObject(workbooks);
                    Marshal.ReleaseComObject(excel);

                    worksheet = null;
                    workbook = null;
                    workbooks = null;
                    excel = null;

                    GC.Collect();
                }
            }
        }

View Code
金沙注册送58 3

public void OutputClient(FileInfo file)
        {
            HttpContext.Current.Response.Buffer = true;

            HttpContext.Current.Response.Clear();
            HttpContext.Current.Response.ClearHeaders();
            HttpContext.Current.Response.ClearContent();

            HttpContext.Current.Response.ContentType = "application/vnd.ms-excel";

            //导出到 .xlsx 格式不能用时,可以试试这个
            //HttpContext.Current.Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";

            HttpContext.Current.Response.AddHeader("Content-Disposition", string.Format("attachment; filename={0}.xlsx", DateTime.Now.ToString("yyyy-MM-dd-HH-mm")));

            HttpContext.Current.Response.Charset = "GB2312";
            HttpContext.Current.Response.ContentEncoding = Encoding.GetEncoding("GB2312");

            HttpContext.Current.Response.AddHeader("Content-Length", file.Length.ToString());

            HttpContext.Current.Response.WriteFile(file.FullName);
            HttpContext.Current.Response.Flush();

            HttpContext.Current.Response.Close();
        }

View Code

的各样方法总括,VSTO学习笔记。第二种情势质量实在是不敢恭维,而且局限性太多。首先必供给安装
office(假使计算机方面没有的话),而且导出时索要内定文件保留的门径。也得以输出到浏览器下载,当然前提是现已保存写入数据。

 

第二种:使用 Aspose.Cells.dll

本条 Aspose.Cells 是 Aspose 公司推出的导出 Excel 的控件,不依赖Office,商业软件,收费的。

能够参见:

金沙注册送58 4

public void ExportExcel(DataTable dt)
        {
            try
            {
                //获取指定虚拟路径的物理路径
                string path = HttpContext.Current.Server.MapPath("DLL/") + "License.lic";

                //读取 License 文件
                Stream stream = (Stream)File.OpenRead(path);

                //注册 License
                Aspose.Cells.License li = new Aspose.Cells.License();
                li.SetLicense(stream);

                //创建一个工作簿
                Aspose.Cells.Workbook workbook = new Aspose.Cells.Workbook();

                //创建一个 sheet 表
                Aspose.Cells.Worksheet worksheet = workbook.Worksheets[0];

                //设置 sheet 表名称
                worksheet.Name = dt.TableName;

                Aspose.Cells.Cell cell;

                int rowIndex = 0;   //行的起始下标为 0
                int colIndex = 0;   //列的起始下标为 0

                //设置列名
                for (int i = 0; i < dt.Columns.Count; i++)
                {
                    //获取第一行的每个单元格
                    cell = worksheet.Cells[rowIndex, colIndex + i];

                    //设置列名
                    cell.PutValue(dt.Columns[i].ColumnName);

                    //设置字体
                    cell.Style.Font.Name = "Arial";

                    //设置字体加粗
                    cell.Style.Font.IsBold = true;

                    //设置字体大小
                    cell.Style.Font.Size = 12;

                    //设置字体颜色
                    cell.Style.Font.Color = System.Drawing.Color.Black;

                    //设置背景色
                    cell.Style.BackgroundColor = System.Drawing.Color.LightGreen;
                }

                //跳过第一行,第一行写入了列名
                rowIndex++;

                //写入数据
                for (int i = 0; i < dt.Rows.Count; i++)
                {
                    for (int j = 0; j < dt.Columns.Count; j++)
                    {
                        cell = worksheet.Cells[rowIndex + i, colIndex + j];

                        cell.PutValue(dt.Rows[i][j]);
                    }
                }

                //自动列宽
                worksheet.AutoFitColumns();

                //设置导出文件路径
                path = HttpContext.Current.Server.MapPath("Export/");

                //设置新建文件路径及名称
                string savePath = path + DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss") + ".xlsx";

                //创建文件
                FileStream file = new FileStream(savePath, FileMode.CreateNew);

                //关闭释放流,不然没办法写入数据
                file.Close();
                file.Dispose();

                //保存至指定路径
                workbook.Save(savePath);


                //或者使用下面的方法,输出到浏览器下载。
                //byte[] bytes = workbook.SaveToStream().ToArray();
                //OutputClient(bytes);

                worksheet = null;
                workbook = null;
            }
            catch(Exception ex)
            {

            }
        }

View Code
金沙注册送58 5

public void OutputClient(byte[] bytes)
        {
            HttpContext.Current.Response.Buffer = true;

            HttpContext.Current.Response.Clear();
            HttpContext.Current.Response.ClearHeaders();
            HttpContext.Current.Response.ClearContent();

            HttpContext.Current.Response.ContentType = "application/vnd.ms-excel";
            HttpContext.Current.Response.AddHeader("Content-Disposition", string.Format("attachment; filename={0}.xls", DateTime.Now.ToString("yyyy-MM-dd-HH-mm")));

            HttpContext.Current.Response.Charset = "GB2312";
            HttpContext.Current.Response.ContentEncoding = Encoding.GetEncoding("GB2312");

            HttpContext.Current.Response.BinaryWrite(bytes);
            HttpContext.Current.Response.Flush();

            HttpContext.Current.Response.Close();
        }

View Code

第①种办法品质还不易,而且操作也不复杂,能够安装导出时文件保留的路子,还足以保留为流输出到浏览器下载。

 

第三种:Microsoft.Jet.OLEDB

那种办法操作 Excel 类似于操作数据库。上边先介绍一下连接字符串:

// Excel 2003 版本连接字符串
string strConn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:/xxx.xls;Extended Properties='Excel 8.0;HDR=Yes;IMEX=2;'";

// Excel 2007 以上版本连接字符串
string strConn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:/xxx.xlsx;Extended Properties='Excel 12.0;HDR=Yes;IMEX=2;'";

Provider:驱动程序名称

Data Source:钦定 Excel 文件的不二法门

Extended Properties:Excel 8.0 针对 Excel 3000 及以上版本;Excel 12.0
针对 Excel 2006 及以上版本。

HDSportage:Yes 表示第1行李包裹括列名,在总括行数时就不分包第①行。NO 则统统相反。

IMEX:0 写入方式;1 读取情势;2 读写形式。若是报错为“无法修改表 sheet1
的安插性。它在只读数据库中”,这就去掉那几个,难点消除。

金沙注册送58 6

public void ExportExcel(DataTable dt)
        {
            OleDbConnection conn = null;
            OleDbCommand cmd = null;

            Microsoft.Office.Interop.Excel.Application excel = new Microsoft.Office.Interop.Excel.Application();

            Microsoft.Office.Interop.Excel.Workbooks workbooks = excel.Workbooks;

            Microsoft.Office.Interop.Excel.Workbook workbook = workbooks.Add(true);

            try
            {
                //设置区域为当前线程的区域
                dt.Locale = System.Threading.Thread.CurrentThread.CurrentCulture;

                //设置导出文件路径
                string path = HttpContext.Current.Server.MapPath("Export/");

                //设置新建文件路径及名称
                string savePath = path + DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss") + ".xlsx";

                //创建文件
                FileStream file = new FileStream(savePath, FileMode.CreateNew);

                //关闭释放流,不然没办法写入数据
                file.Close();
                file.Dispose();

                //由于使用流创建的 excel 文件不能被正常识别,所以只能使用这种方式另存为一下。
                workbook.SaveCopyAs(savePath);


                // Excel 2003 版本连接字符串
                //string strConn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source='" + savePath + "';Extended Properties='Excel 8.0;HDR=Yes;'";

                // Excel 2007 以上版本连接字符串
                string strConn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source='"+ savePath + "';Extended Properties='Excel 12.0;HDR=Yes;'";

                //创建连接对象
                conn = new OleDbConnection(strConn);
                //打开连接
                conn.Open();

                //创建命令对象
                cmd = conn.CreateCommand();

                //获取 excel 所有的数据表。
                //new object[] { null, null, null, "Table" }指定返回的架构信息:参数介绍
                //第一个参数指定目录
                //第二个参数指定所有者
                //第三个参数指定表名
                //第四个参数指定表类型
                DataTable dtSheetName = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, new object[] { null, null, null, "Table" });

                //因为后面创建的表都会在最后面,所以本想删除掉前面的表,结果发现做不到,只能清空数据。
                for (int i = 0; i < dtSheetName.Rows.Count; i++)
                {
                    cmd.CommandText = "drop table [" + dtSheetName.Rows[i]["TABLE_NAME"].ToString() + "]";
                    cmd.ExecuteNonQuery();
                }

                //添加一个表,即 Excel 中 sheet 表
                cmd.CommandText = "create table " + dt.TableName + " ([S_Id] INT,[S_StuNo] VarChar,[S_Name] VarChar,[S_Sex] VarChar,[S_Height] VarChar,[S_BirthDate] VarChar,[C_S_Id] INT)";
                cmd.ExecuteNonQuery();

                for (int i = 0; i < dt.Rows.Count; i++)
                {
                    string values = "";

                    for (int j = 0; j < dt.Columns.Count; j++)
                    {
                        values += "'" + dt.Rows[i][j].ToString() + "',";
                    }

                    //判断最后一个字符是否为逗号,如果是就截取掉
                    if (values.LastIndexOf(',') == values.Length - 1)
                    {
                        values = values.Substring(0, values.Length - 1);
                    }

                    //写入数据
                    cmd.CommandText = "insert into " + dt.TableName + " (S_Id,S_StuNo,S_Name,S_Sex,S_Height,S_BirthDate,C_S_Id) values (" + values + ")";
                    cmd.ExecuteNonQuery();
                }

                conn.Close();
                conn.Dispose();
                cmd.Dispose();

                //加入下面的方法,把保存的 Excel 文件输出到浏览器下载。需要先关闭连接。
                FileInfo fileInfo = new FileInfo(savePath);
                OutputClient(fileInfo);
            }
            catch (Exception ex)
            {

            }
            finally
            {
                workbook.Close(false, Type.Missing, Type.Missing);
                workbooks.Close();
                excel.Quit();

                Marshal.ReleaseComObject(workbook);
                Marshal.ReleaseComObject(workbooks);
                Marshal.ReleaseComObject(excel);

                workbook = null;
                workbooks = null;
                excel = null;

                GC.Collect();
            }
        }

View Code
金沙注册送58 7

public void OutputClient(FileInfo file)
        {
            HttpResponse response = HttpContext.Current.Response;

            response.Buffer = true;

            response.Clear();
            response.ClearHeaders();
            response.ClearContent();

            response.ContentType = "application/vnd.ms-excel";

            //导出到 .xlsx 格式不能用时,可以试试这个
            //HttpContext.Current.Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";

            response.AddHeader("Content-Disposition", string.Format("attachment; filename={0}.xlsx", DateTime.Now.ToString("yyyy-MM-dd-HH-mm")));

            response.Charset = "GB2312";
            response.ContentEncoding = Encoding.GetEncoding("GB2312");

            response.AddHeader("Content-Length", file.Length.ToString());

            response.WriteFile(file.FullName);
            response.Flush();

            response.Close();
        }

View Code

那种办法须求钦赐贰个早就存在的 Excel
文件作为写入数据的模版,不然的话就得利用流创设多个新的 Excel
文件,不过那样是无可奈何识其余,那就要求用到 Microsoft.Office.Interop.Excel.dll
里面的 Microsoft.Office.Interop.Excel.Workbook.SaveCopyAs()
方法另存为一下,这样质量也就更差了。

运用操作命令创设的表都以在最终边的,前边的也无可怎样删除(笔者是没有找到方法),当然也能够不再成立,直接写入数据也得以。

 

第四种:NPOI

NPOI 是 POI 项目的.NET版本,它不利用 Office COM 组件,不需求安装
Microsoft Office,最近只帮助 Office 97-二〇〇四 的文件格式。

NPOI 是免费开源的,操作也正如便宜,下载地址:

金沙注册送58 8

public void ExportExcel(DataTable dt)
        {
            try
            {
                //创建一个工作簿
                IWorkbook workbook = new HSSFWorkbook();

                //创建一个 sheet 表
                ISheet sheet = workbook.CreateSheet(dt.TableName);

                //创建一行
                IRow rowH = sheet.CreateRow(0);

                //创建一个单元格
                ICell cell = null;

                //创建单元格样式
                ICellStyle cellStyle = workbook.CreateCellStyle();

                //创建格式
                IDataFormat dataFormat = workbook.CreateDataFormat();

                //设置为文本格式,也可以为 text,即 dataFormat.GetFormat("text");
                cellStyle.DataFormat = dataFormat.GetFormat("@");

                //设置列名
                foreach (DataColumn col in dt.Columns)
                {
                    //创建单元格并设置单元格内容
                    rowH.CreateCell(col.Ordinal).SetCellValue(col.Caption);

                    //设置单元格格式
                    rowH.Cells[col.Ordinal].CellStyle = cellStyle;
                }

                //写入数据
                for (int i = 0; i < dt.Rows.Count; i++)
                {
                    //跳过第一行,第一行为列名
                    IRow row = sheet.CreateRow(i + 1);

                    for (int j = 0; j < dt.Columns.Count; j++)
                    {
                        cell = row.CreateCell(j);
                        cell.SetCellValue(dt.Rows[i][j].ToString());
                        cell.CellStyle = cellStyle;
                    }
                }

                //设置导出文件路径
                string path = HttpContext.Current.Server.MapPath("Export/");

                //设置新建文件路径及名称
                string savePath = path + DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss") + ".xls";

                //创建文件
                FileStream file = new FileStream(savePath, FileMode.CreateNew,FileAccess.Write);

                //创建一个 IO 流
                MemoryStream ms = new MemoryStream();

                //写入到流
                workbook.Write(ms);

                //转换为字节数组
                byte[] bytes = ms.ToArray();

                file.Write(bytes, 0, bytes.Length);
                file.Flush();

                //还可以调用下面的方法,把流输出到浏览器下载
                OutputClient(bytes);

                //释放资源
                bytes = null;

                ms.Close();
                ms.Dispose();

                file.Close();
                file.Dispose();

                workbook.Close();
                sheet = null;
                workbook = null;
            }
            catch(Exception ex)
            {

            }
        }

View Code
金沙注册送58 9

public void OutputClient(byte[] bytes)
        {
            HttpResponse response = HttpContext.Current.Response;

            response.Buffer = true;

            response.Clear();
            response.ClearHeaders();
            response.ClearContent();

            response.ContentType = "application/vnd.ms-excel";
            response.AddHeader("Content-Disposition", string.Format("attachment; filename={0}.xls", DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss")));

            response.Charset = "GB2312";
            response.ContentEncoding = Encoding.GetEncoding("GB2312");

            response.BinaryWrite(bytes);
            response.Flush();

            response.Close();
        }

View Code

由于此方法如今只援助 office 2000 及以下版本,所以不可能导出 .xlsx 格式的
Excel 文件。不过那种艺术品质不错,而且操作方便。

 

导出 Excel 的各类艺术计算, 第①种:使用
Microsoft.Office.Interop.Excel.dll 首先须求设置 office 的
excel,然后再找到Microsoft.Office.Interop.Excel.d…

在相似的管制系列模块里面,越多的统一筹划到一些常用文书档案的上传保存操作,个中如PDF、Word、Excel等文档,有时候是经过分布式的WCF技术完成数量的显得和拍卖,由此期望直接预览而不供给下载文件,那样能够给大家提供许多的有利。在DevExpress里面,提供了相应的控件来体现和处理那一个文书档案,本文重要介绍怎么着行使DevExpress的控件达成对PDF、Word、Excel文书档案的预览和操作处理。

接触VSTO纯属偶然,前段时间因为费力三个体系,在客户端Excel中创设二个插件,从远程服务器端(SharePoint
Excel
瑟维斯s)上下载Excel到地点打开,用户编辑后再上传回服务器端。当时工期迫切,近来查了些资料,用VSTO

本条时候C#出现了,发现使用C#来操作Excel卓殊有利,比VBA不知道高到哪个地方去了,而且一向就足以上手,所以作者就把常用的一对操作封装成了2个类,编写翻译成DLL方便在一一档次中调用。

壹 、PDF的预览和操作

在较早的DevExpress的控件里面,已经提供了相应的PDF文书档案的展现控件,但是由于其对PDF格式支持不是很好,有个别文书档案是Office导出的,也不是很健康阅读,由此很少使用,本文介绍的DevExpress的PDF查看控件是基于14.1的,测试过众多文书档案,好像都能平常打开,因而也想在系统中广大应用了。

为了演示那几个控件的拍卖,小编独自编写制定了一个例子,用来促成对PDF、Word、Excel等文书档案的拍卖。

金沙注册送58 10

为了呈现PDF文书档案,大家须求在界面里面添加三个XtraPdfViewer.PdfViewer的控件,这些重点是用来呈现PDF的,它有很多属性方法,用来兑现对PDF的处理操作,测试界面设计好如下所示。

金沙注册送58 11

对PDF,我们一般首尽管用来打开文件,另存为,或许预览就能够了。相关的操作代码如下所示。

    /// <summary>
    /// PDF测试显示窗体
    /// </summary>
    public partial class PDFViewer : Form
    {
        //记录窗体的名称
        readonly string mainFormText;

        public PDFViewer()
        {
            InitializeComponent();

            //记录窗体的名称,并实现文档变化事件的处理,方便显示新的文件名称
            mainFormText = this.Text;
            pdfViewer1.DocumentChanged += new DevExpress.XtraPdfViewer.PdfDocumentChangedEventHandler(pdfViewer1_DocumentChanged);
        }

        /// <summary>
        /// PDF文档变化后,实现对新文件名称的显示
        /// </summary>
        void pdfViewer1_DocumentChanged(object sender, DevExpress.XtraPdfViewer.PdfDocumentChangedEventArgs e)
        {
            string fileName = Path.GetFileName(e.DocumentFilePath);
            if (String.IsNullOrEmpty(fileName))
            {
                Text = mainFormText;
            }
            else
            {
                Text = fileName + " - " + mainFormText;
            }
        }

        /// <summary>
        /// 打开PDF文件
        /// </summary>
        private void btnOpenFile_Click(object sender, EventArgs e)
        {
            string filePath = FileDialogHelper.OpenPdf();
            if (!string.IsNullOrEmpty(filePath))
            {
                this.pdfViewer1.LoadDocument(filePath);
            }
        }

        /// <summary>
        /// 另存为PDF文件
        /// </summary>
        private void btnSaveAs_Click(object sender, EventArgs e)
        {
            string dir = System.Environment.CurrentDirectory;
            string filePath = FileDialogHelper.SavePdf("", dir);
            if (!string.IsNullOrEmpty(filePath))
            {
                try
                {
                    this.pdfViewer1.SaveDocument(filePath);
                    MessageUtil.ShowTips("保存成功");
                }
                catch (Exception ex)
                {
                    LogTextHelper.Error(ex);
                    MessageUtil.ShowError(ex.Message);
                }
            }
        }

        /// <summary>
        /// PDF文件打印
        /// </summary>
        private void btnPreview_Click(object sender, EventArgs e)
        {
            this.pdfViewer1.Print();
        }
    }

从上边的代码,我们得以见见,对于PDF,大家操作起来很便利,重要正是在界面里面加载文件后,就足以对PDFViewer对象完成相关的操作了。

 

  • 金沙注册送58 ,Excel COM
    API形成。正因为这些项目,小编意识了VSTO的有力效率与潜力,决定抽出部分年华来好好研讨下。

实在使用第③方控件也足以落成相应的功用,而且一些控件也是选取Visual
Studio Tools for Office
(VSTO)中相同风格的接口,间接就足以上手,可是好用的都以要付钱的。那里不做探究。

② 、WO福特ExplorerD文档的预览和操作

接近于PDF文书档案,我们对WORAV4D文书档案,也是经过行使Rich艾德itControl完毕文书档案的来得,但是和PDFViewer区别,这么些控件能够兑现对文书档案的改动和保存操作,这种对于大家提供用户对文档进行编辑很便宜。

测试例子的界面如下所示。

金沙注册送58 12

连带的操作代码,也和PDF的操作看似,不一样的是,它在文书档案变化后,不能够很不难从参数里面获取到对应的文书档案的路径,供给新鲜的拍卖才能获得。

    /// <summary>
    /// WORD控件的测试例子
    /// </summary>
    public partial class WordViewer : Form
    {
        //记录窗体的名称
        readonly string mainFormText;

        public WordViewer()
        {
            InitializeComponent();

            //记录窗体的名称,并实现文档变化事件的处理,方便显示新的文件名称
            mainFormText = this.Text;
            this.richEditControl1.DocumentLoaded += new EventHandler(richEditControl1_DocumentLoaded);
        }

        /// <summary>
        /// WORD文档变化后,实现对新文件名称的显示
        /// </summary>
        void richEditControl1_DocumentLoaded(object sender, EventArgs e)
        {
            string fileName = Path.GetFileName(this.richEditControl1.Options.DocumentSaveOptions.CurrentFileName);
            if (String.IsNullOrEmpty(fileName))
            {
                Text = mainFormText;
            }
            else
            {
                Text = fileName + " - " + mainFormText;
            }

            //修改默认字体
            DocumentRange range = richEditControl1.Document.Range;
            CharacterProperties cp = this.richEditControl1.Document.BeginUpdateCharacters(range);
            cp.FontName = "新宋体";
            //cp.FontSize = 12;
            this.richEditControl1.Document.EndUpdateCharacters(cp);
        }

        /// <summary>
        /// 打开WORD文件
        /// </summary>
        private void btnOpenFile_Click(object sender, EventArgs e)
        {
            string filePath = FileDialogHelper.OpenWord();
            if (!string.IsNullOrEmpty(filePath))
            {
                richEditControl1.LoadDocument(filePath);//, DocumentFormat.Doc);
            }
        }

        /// <summary>
        /// 保存WORD文件
        /// </summary>
        private void btnSaveFile_Click(object sender, EventArgs e)
        {
            this.richEditControl1.SaveDocument();
        }

        /// <summary>
        /// 另存为WORD文件
        /// </summary>
        private void btnSaveAs_Click(object sender, EventArgs e)
        {
            try
            {
                richEditControl1.SaveDocumentAs();
                MessageUtil.ShowTips("保存成功");
            }
            catch (Exception ex)
            {
                LogTextHelper.Error(ex);
                MessageUtil.ShowError(ex.Message);
            }
        }

        /// <summary>
        /// WORD文件打印
        /// </summary>
        private void btnPreview_Click(object sender, EventArgs e)
        {
            this.richEditControl1.ShowPrintPreview();
        }
    }

加载文书档案后,界面突显内容如下所示:

金沙注册送58 13

文书档案控件很简单援救打字与印刷预览功效,打字与印刷预览的界面如下所示

金沙注册送58 14

但是话说回来,这么些Rich艾德itControl尽管能够较好显示Word文书档案,可是也有部分字体展现的不是很好,格式和微软的Word软件展现的多少不太一致,格式有所损失。

之所以一旦对于格式须要相比较谨慎的,提议如故只是做显示为佳,不要保存原有的文书档案。假设对格式不是专程严峻,倒是能够视作多个文书档案服务器完成文书档案的新建、保存处理。

 

演示代码下载

 

③ 、Excel文书档案的预览和操作

对于Excel文书档案的预览和操作,DevExpress控件在近年版本中追加的XtraSpreadsheet.SpreadsheetControl控件就能够兑现Excel的体现和处理操作,那些控件很强大,能够处理很复杂格式的Excel文书档案,即便作者原本选用了此外贰个FarPoint
Spread控件组,然而那些XtraSpreadsheet控件组,假如集成在DevExpress也就很有益于了。

金沙注册送58 15

这一个DevExpress的控件,可以在内部举办Excel的新建、保存、打字与印刷预览等操作,当然也能够打开大家已有的Excel文件了。

开拓文件后,界面效果如下所示。

金沙注册送58 16

界面的有关功效操作代码如下所示。

    /// <summary>
    /// Excel控件的测试例子
    /// </summary>
    public partial class ExcelViewer : Form
    {
        //记录窗体的名称
        readonly string mainFormText;

        public ExcelViewer()
        {
            InitializeComponent();

            //记录窗体的名称,并实现文档变化事件的处理,方便显示新的文件名称
            mainFormText = this.Text;
            this.spreadsheetControl1.DocumentLoaded += new EventHandler(spreadsheetControl1_DocumentLoaded);
        }

        /// <summary>
        /// 文档变化后,实现对新文件名称的显示
        /// </summary>
        void spreadsheetControl1_DocumentLoaded(object sender, EventArgs e)
        {
            string fileName = Path.GetFileName(this.spreadsheetControl1.Document.Path);
            if (String.IsNullOrEmpty(fileName))
            {
                Text = mainFormText;
            }
            else
            {
                Text = fileName + " - " + mainFormText;
            }
        }

        /// <summary>
        /// 打开Excel文件
        /// </summary>
        private void btnOpenFile_Click(object sender, EventArgs e)
        { 
            string filePath = FileDialogHelper.OpenExcel();
            if (!string.IsNullOrEmpty(filePath))
            {
                IWorkbook workbook = spreadsheetControl1.Document;
                workbook.LoadDocument(filePath);
            }
        }

        /// <summary>
        /// 保存Excel文件
        /// </summary>
        private void btnSaveFile_Click(object sender, EventArgs e)
        {
            spreadsheetControl1.SaveDocument();
        }

        /// <summary>
        /// 另存为Excel文件
        /// </summary>
        private void btnSaveAs_Click(object sender, EventArgs e)
        {
            string dir = System.Environment.CurrentDirectory;
            string filePath = FileDialogHelper.SaveExcel("", dir);
            if (!string.IsNullOrEmpty(filePath))
            {
                try
                {
                    IWorkbook workbook = spreadsheetControl1.Document;
                    workbook.SaveDocument(filePath);

                    MessageUtil.ShowTips("保存成功");
                }
                catch (Exception ex)
                {
                    LogTextHelper.Error(ex);
                    MessageUtil.ShowError(ex.Message);
                }
            }
        }

        /// <summary>
        /// Excel文件打印
        /// </summary>
        private void btnPreview_Click(object sender, EventArgs e)
        {
            this.spreadsheetControl1.ShowPrintPreview();
        }
    }

 

预览也很便宜,和Word的预览操作看似。

金沙注册送58 17

 

以上正是多少个常用文书档案的来得和操作案例,有了这几个大家很不难整合到大家的附件管理内部了。

如本身在自个儿的《Winform开发框架》、《混合式开发框架之中》使用的通用附属类小部件管理模块,正是根据那几个特征,实现图片、Excel文书档案、Word文书档案和PDF等文书档案的在线预览和管制操作,界面截图如下所示。

金沙注册送58 18

 

本连串具有示例代码均在 Visual Studio 二〇〇八 Beta 2 + Office 二〇一〇 Beta
下测试通过 

先是要添加程序集引用:Microsoft.Office.Interop.Excel,因为大家运用的是OFFICE2015,所以选取15.0.0.0版本。

 

金沙注册送58 19

一、什么是VSTO?

 

VSTO = Visual Studo Tools for
Office,是.net平台下的Office开发技术。相对于守旧的VBA(Visual Basic
Application)开发,VSTO为中高等开发职员提供了越来越强硬的支出平台和言语,并部分缓解了古板Office开发中的诸多难点(难于更新、可扩展性差、难以维护、安全性低等),开发人士能够使用深谙的技术来创设尤其灵敏的、强大的、跨平台的商家级化解方案。

要是继承Excel那些抽象类并落到实处handler方法即可。

② 、为何要举行Office开发?

 

    Office拥有强大的数据解析、展现和计量能力,越发在桌面领域,已经变为了办公自动化的行业标准。尽管Office功用强大,然而也不只怕满足各行各业的一定需要,如若能够借助Office营造集团的特性需要,那将拾贰分有着吸重力。那样,在不必要其他标准软件的图景下,就恐怕达成既定的指标。

  1 using System;
  2 using System.Collections.Generic;
  3 using System.Diagnostics;
  4 using System.Runtime.InteropServices;
  5 using Microsoft.Office.Interop.Excel;
  6 using System.IO;
  7 using static System.IO.File;
  8 
  9 namespace ExcelHelper
 10 {
 11     /*
 12      2018-08-17 13:43:53
 13      luoc@zhiweicl.com
 14          */
 15     /// <summary>
 16     /// Excel抽象类,封装了常用的方法,只需要实现Hanlder方法即可。
 17     /// </summary>
 18     public abstract class Excel
 19     {
 20         /// <summary>
 21         /// 实例化Excel对象
 22         /// </summary>
 23         /// <param name="debugMode">设置Debug模式(Excel可见性,屏幕刷新,不提示警告窗体)</param>
 24         protected Excel(bool debugMode = true)
 25         {
 26             try
 27             {
 28                 ExcelApp = GetExcelApplication();
 29                 DebugMode = debugMode;
 30             }
 31             catch (InvalidCastException)
 32             {
 33                 throw new COMException("对不起,没有获取到本机安装的Excel对象,请尝试修复或者安装Office2016后使用本软件!");
 34             }
 35         }
 36 
 37         /// <summary>
 38         /// 显示Excel窗口
 39         /// </summary>
 40         public void Show()
 41         {
 42             if (!ExcelApp.Visible)
 43             {
 44                 ExcelApp.Visible = true;
 45             }
 46         }
 47 
 48         /// <summary>
 49         /// 获取Excel对象,如果不存在则打开
 50         /// </summary>
 51         /// <returns>返回一个Excel对象</returns>
 52         public Application GetExcelApplication()
 53         {
 54             Application application;
 55             try
 56             {
 57                 application = (Application)Marshal.GetActiveObject("Excel.Application");//尝试取得正在运行的Excel对象
 58                 Debug.WriteLine("Get Running Excel");
 59             }
 60             //没有打开Excel则会报错
 61             catch (COMException)
 62             {
 63                 application = CreateExcelApplication();//打开Excel
 64                 Debug.WriteLine("Create new Excel");
 65             }
 66             Debug.WriteLine(application.Version);//打印Excel版本
 67             return application;
 68         }
 69 
 70         /// <summary>
 71         /// 创建一个Excel对象
 72         /// </summary>
 73         /// <param name="visible">是否显示Excel,默认为True</param>
 74         /// <param name="caption">标题栏</param>
 75         /// <returns>返回创建好的Excel对象</returns>
 76         public Application CreateExcelApplication(bool visible = true, string caption = "New Application")
 77         {
 78             var application = new Application
 79             {
 80                 Visible = visible,
 81                 Caption = caption
 82             };
 83             return application;
 84         }
 85 
 86         /// <summary>
 87         /// 退出Excel
 88         /// </summary>
 89         public void Exit()
 90         {
 91             if (ExcelApp.Workbooks.Count > 0)
 92             {
 93                 ExcelApp.DisplayAlerts = false;
 94                 ExcelApp.Workbooks.Close(); //关闭所有工作簿
 95             }
 96             ExcelApp.Quit(); //退出Excel
 97             ExcelApp.DisplayAlerts = true;
 98         }
 99         /// <summary>
100         /// 杀死Excel进程
101         /// </summary>
102         public void Kill()
103         {
104             if (ExcelApp.Workbooks.Count > 0)
105             {
106                 ExcelApp.DisplayAlerts = false;
107                 ExcelApp.Workbooks.Close(); //关闭所有工作簿
108             }
109             ExcelApp.Quit();
110             GC.Collect();
111             KeyMyExcelProcess.Kill(ExcelApp);
112         }
113         /// <summary>
114         /// Excel实例对象
115         /// </summary>
116         public Application ExcelApp { get; }
117 
118         /// <summary>
119         /// 获取workbook对象
120         /// </summary>
121         /// <param name="name">工作簿全名</param>
122         /// <returns></returns>
123         public Workbook GetWorkbook(string name)
124         {
125             var wbk = ExcelApp.Workbooks[name];
126             return wbk;
127         }
128 
129         /// <summary>
130         /// 获取workbook对象
131         /// </summary>
132         /// <param name="index">索引</param>
133         /// <returns></returns>
134         public Workbook GetWorkbook(int index)
135         {
136             var wbk = ExcelApp.Workbooks[index];
137             return wbk;
138         }
139 
140         /// <summary>
141         /// 获取workbook活动对象
142         /// </summary>
143         /// <returns></returns>
144         public Workbook GetWorkbook()
145         {
146             var wbk = ExcelApp.ActiveWorkbook;
147             return wbk;
148         }
149 
150         /// <summary>
151         /// 打开工作簿
152         /// </summary>
153         /// <param name="path"></param>
154         /// <returns></returns>
155         public Workbook OpenFromFile(string path)
156         {
157             var workbook = ExcelApp.Workbooks.Open(path);
158             return workbook;
159         }
160 
161         /// <summary>
162         /// 添加工作簿
163         /// </summary>
164         /// <returns></returns>
165         public Workbook AddWorkbook()
166         {
167             var workbook = ExcelApp.Workbooks.Add();
168             return workbook;
169         }
170 
171         /// <summary>
172         /// 保存工作簿
173         /// </summary>
174         /// <param name="workbook"></param>
175         /// <param name="path"></param>
176         public void SaveWorkbook(Workbook workbook, string path)
177         {
178             workbook.SaveAs(path);
179         }
180 
181         /// <summary>
182         /// 关闭工作簿
183         /// </summary>
184         /// <param name="workbook"></param>
185         public void CloseWorkbook(Workbook workbook)
186         {
187             workbook.Close(false, Type.Missing, Type.Missing);
188         }
189 
190         /// <summary>
191         /// 打开或者查找表
192         /// </summary>
193         /// <param name="path"></param>
194         /// <param name="filename"></param>
195         /// <returns></returns>
196         public Workbook OpenAndFindWorkbook(string path, string filename)
197         {
198             var pathFull = Path.Combine(path, filename);
199             string fileName;
200             if (!Exists(pathFull))
201             {
202                 pathFull = Directory.GetFiles(path, filename)[0];
203                 fileName = Path.GetFileName(pathFull);
204             }
205             else
206             {
207                 fileName = Path.GetFileName(filename);
208             }
209 
210 
211             Workbook res = null;
212             //遍历所有已打开的工作簿
213             foreach (Workbook ws in ExcelApp.Workbooks)
214             {
215                 if (ws.Name != fileName) continue;
216                 res = GetWorkbook(fileName); //OpenFromFile(umts_path).Worksheets[1];
217                 break;
218             }
219 
220             //如果没有找到就直接打开文件
221             return res ?? (OpenFromFile(pathFull));
222         }
223 
224         /// <summary>
225         /// 打开或者查找表
226         /// </summary>
227         /// <param name="filename">文件名全路径</param>
228         /// <returns></returns>
229         public Workbook OpenAndFindWorkbook(string filename)
230         {
231             var pathFull = filename;
232             string fileName;
233             var path = Path.GetDirectoryName(filename);
234             if (!Exists(pathFull))
235             {
236                 pathFull = Directory.GetFiles(path ?? throw new InvalidOperationException(), filename)[0];
237                 fileName = Path.GetFileName(pathFull);
238             }
239             else
240             {
241                 fileName = Path.GetFileName(filename);
242             }
243 
244 
245             Workbook res = null;
246             //遍历所有已打开的工作簿
247             foreach (Workbook ws in ExcelApp.Workbooks)
248             {
249                 if (ws.Name != fileName) continue;
250                 res = GetWorkbook(fileName); //OpenFromFile(umts_path).Worksheets[1];
251                 break;
252             }
253 
254             //如果没有找到就直接打开文件
255             return res ?? (OpenFromFile(pathFull));
256         }
257 
258         /// <summary>
259         /// 复制列到另一张表
260         /// </summary>
261         /// <param name="sourceWorksheet">源表</param>
262         /// <param name="sourceRows">源列</param>
263         /// <param name="sourceStart">起始位置</param>
264         /// <param name="newWorksheet">目的表</param>
265         /// <param name="newRows">目的列</param>
266         /// <param name="newStart">目的位置</param>
267         public void CopyRow2OtherSheet(Worksheet sourceWorksheet, string[] sourceRows, int sourceStart,
268             Worksheet newWorksheet, string[] newRows, int newStart)
269         {
270             int intrngEnd = GetEndRow(sourceWorksheet);
271             if (newRows != null && (sourceRows != null && sourceRows.Length == newRows.Length))
272             {
273                 for (int i = 0; i < sourceRows.Length; i++)
274                 {
275                     var rg = sourceRows[i] + sourceStart + ":" + sourceRows[i] + intrngEnd;
276                     sourceWorksheet.Range[rg]
277                         .Copy(newWorksheet.Range[newRows[i] + newStart]);
278                     //  new_worksheet.Cells[65536, new_rows[i]].End[XlDirection.xlUp].Offset(1, 0).Resize(intrngEnd, 1).Value = source_worksheet.Cells[2, source_rows[i]].Resize(intrngEnd, new_rows[i]).Value;
279                 }
280             }
281             else
282             {
283                 Console.WriteLine("Error source_rows length not is new_rows length!");
284             }
285         }
286 
287         /// <summary>
288         /// 复制列到另一张表
289         /// </summary>
290         /// <param name="sourceWorksheet">源表</param>
291         /// <param name="sourceRows">源列</param>
292         /// <param name="sourceStart">起始位置</param>
293         /// <param name="newWorksheet">目的表</param>
294         /// <param name="newRows">目的列</param>
295         /// <param name="newStart">目的位置</param>
296         public void CopyRow2OtherSheet(Worksheet sourceWorksheet, int[] sourceRows, int sourceStart, Worksheet newWorksheet,
297             int[] newRows, int newStart)
298         {
299             int intrngEnd = GetEndRow(sourceWorksheet);
300             if (sourceRows.Length == newRows.Length)
301             {
302                 for (int i = 0; i < sourceRows.Length; i++)
303                 {
304                     newWorksheet.Cells[65536, newRows[i]].End[XlDirection.xlUp].Offset(sourceStart, 0).Resize(intrngEnd, sourceStart)
305                         .Value = sourceWorksheet.Cells[newStart, sourceRows[i]].Resize(intrngEnd, newRows[i]).Value;
306                 }
307             }
308             else
309             {
310                 Console.WriteLine("Error source_rows length not is new_rows length!");
311             }
312         }
313 
314         /// <summary>
315         /// 复制表头到另一个sheet中
316         /// </summary>
317         /// <param name="sourceWorksheet">表头所在的sheet</param>
318         /// <param name="newWorksheet">要复制到的sheet</param>
319         /// <param name="start">起始位置</param>
320         public void CopyHeader(Worksheet sourceWorksheet, Worksheet newWorksheet, int start = 1)
321         {
322             if (sourceWorksheet.Rows != null)
323                 sourceWorksheet.Rows[start].Copy(newWorksheet.Cells[1, 1]); //把数据表的表头复制到新表中
324         }
325 
326         /// <summary>
327         /// 设置特定列的数据
328         /// </summary>
329         /// <param name="worksheet">源表</param>
330         /// <param name="row">要设置的列号</param>
331         /// <param name="len">长度</param>
332         /// <param name="value">要设的值</param>
333         /// ///
334         public void SetSheetRow(Worksheet worksheet, int row, int len, string value)
335         {
336             //int intrngEnd = this.GetEndRow(worksheet);//取特定列最后一列的长度
337             worksheet.Cells[65536, row].End[XlDirection.xlUp].Offset(1, 0).Resize(len, 1).Value = value;
338         }
339 
340         /// <summary>
341         /// 取有效列的最后一列的长度
342         /// </summary>
343         /// <param name="worksheet"></param>
344         /// <returns></returns>
345         public int GetEndRow(Worksheet worksheet)
346         {
347             int res = worksheet.UsedRange.Rows.Count;
348             return res;
349         }
350 
351         /// <summary>
352         /// 插入图片
353         /// </summary>
354         /// <param name="path">图片路径</param>
355         /// <param name="worksheet">要插入的表</param>
356         /// <param name="range">要插入的range</param>
357         public void AddPic(string path, Worksheet worksheet, Range range)
358         {
359             this.AddPic(path, worksheet, range, range.Width, range.Height);
360         }
361 
362         /// <summary>
363         /// 插入图片
364         /// </summary>
365         /// <param name="path">图片路径</param>
366         /// <param name="worksheet">要插入的表</param>
367         /// <param name="range">要插入的range</param>
368         /// <param name="width">图片的宽度</param>
369         /// <param name="height">图片的高度</param>
370         public void AddPic(string path, Worksheet worksheet, Range range, int width, int height)
371         {
372             worksheet.Shapes.AddPicture(path, Microsoft.Office.Core.MsoTriState.msoCTrue,
373                     Microsoft.Office.Core.MsoTriState.msoCTrue, range.Left, range.Top, width, height).Placement =
374                 XlPlacement.xlMoveAndSize;
375         }
376 
377         /// <summary>
378         /// 批量插入图片
379         /// </summary>
380         /// <param name="pngdic">单元格范围-图片名</param>
381         /// <param name="imgBase">图片根目录</param>
382         /// <param name="worksheet">要插入图片的worksheet</param>
383         /// <returns>返回处理好的图片日志</returns>
384         public string InsertMultipleImages(Dictionary<string, string> pngdic, string imgBase, Worksheet worksheet)
385         {
386             string msg = null;
387             foreach (var s in pngdic)
388             {
389                 string imgPath = Path.Combine(imgBase, s.Value);
390                 if (!Exists(imgPath))
391                 {
392                     continue;
393                 }
394 
395                 Range range = worksheet.Range[s.Key];
396                 AddPic(imgPath, worksheet, range);
397                 msg = s.Value + "\t" + s.Key + "\t\t\t" + range.Left.ToString() + "\t" + range.Top.ToString() + "\n";
398             }
399 
400             return msg;
401         }
402 
403         /// <summary>
404         /// 主要实现这个方法
405         /// </summary>
406         /// <param name="path">要打开的文件路径</param>
407         public abstract void Handler(string path = null);
408         /// <summary>
409         /// 开启或者关闭屏幕刷新
410         /// </summary>
411         public bool ScreenUpdating
412         {
413             get => ExcelApp.ScreenUpdating;
414             set => ExcelApp.ScreenUpdating = value;
415         }
416         /// <summary>
417         /// Excel可见性
418         /// </summary>
419         public bool Visible
420         {
421             get => ExcelApp.Visible;
422             set => ExcelApp.Visible = value;
423         }
424         /// <summary>
425         /// 是否显示警告窗体
426         /// </summary>
427         public bool DisplayAlerts
428         {
429             get => ExcelApp.DisplayAlerts;
430             set => ExcelApp.DisplayAlerts = value;
431         }
432         private bool _debugMode;
433         /// <summary>
434         /// 设置DEBUG模式
435         /// </summary>
436         public bool DebugMode
437         {
438             get => _debugMode;
439             set
440             {
441                 _debugMode = value;
442                 //设置是否显示警告窗体
443                 DisplayAlerts = value;
444                 //设置是否显示Excel
445                 Visible = value;
446                 //禁止刷新屏幕
447                 ScreenUpdating = value;
448             }
449         }
450     }
451     /// <summary>
452     /// 关闭Excel进程
453     /// </summary>
454     public class KeyMyExcelProcess
455     {
456         [DllImport("User32.dll", CharSet = CharSet.Auto)]
457         public static extern int GetWindowThreadProcessId(IntPtr hwnd, out int id);
458         public static void Kill(Application excel)
459         {
460             try
461             {
462                 IntPtr t = new IntPtr(excel.Hwnd);   //得到这个句柄,具体作用是得到这块内存入口
463                 GetWindowThreadProcessId(t, out var k);   //得到本进程唯一标志k
464                 System.Diagnostics.Process p = System.Diagnostics.Process.GetProcessById(k);   //得到对进程k的引用
465                 p.Kill();     //关闭进程k
466             }
467             catch (Exception e)
468             {
469                 Console.WriteLine(e.Message);
470             }
471 
472         }
473     }
474 }

三 、Office开发简史

 

1、VBA(Visual Basic Application)

    微软提议的第2种Office开发消除方案正是VBA,在20世纪九十时代VBA欢腾,借助于当时发达的Visual
Basic,VBA获得了了不起的功成名就,无论是专业的开发人士,如故刚入门的非开发人士,都能够选择VBA完毕简单或复杂的需求。然则VBA自身具有广大的局限性,VB语言固然简易,但是其语法令中高等开发职员不太适应,特别是VBA的支出条件过于简短,贫乏与时俱进的尖端功效,使得VBA开发陷入了瓶颈。

2、VSTO 1.0(VSTO 2003)

时光跨入21世纪,微软发表了.net平台,并盛产了新千年的新语言:C#,VBA一统Office开发天下的事态终于有所变更。从Office
贰零零壹发端,Office正式由一个桌面办公平台转化为了桌面开发平台,微软也及时推出了VSTO
二〇〇三,即VSTO
1.0。就是通过起头,Office开发跨入了一个新的方今,开发人士能够选拔尤其高档的语言和熟练的技能来更便于的进行Office开发。VSTO
1.0全然编制程序支持Office 2000和Office
XP,提供了以文书档案为着力的支出平台,开发人士使用.net framework
1.1支出Office中的一些自动化程序等。

3、VSTO 2.0(VSTO 2005 SE)

    VSTO 2.0及其Visual Studio 2007生产,提供了大气新特点:

  1. 提供了新的文书档案模板
  2. 对Word、Excel的可视化协助
  3. 可以选拔托管的Windows Forms控件或机件
  4. 宿主要控制件(不知底翻译的哪些:))    
  5. 帮忙在文书档案中添加智能标签
  6. 动作面板扶助
  7. 数量绑定、数据源、数据模型扶助
  8. 数码缓存
  9. 服务器端编制程序
  10. 布署文件
  11. 新的配备情势
  12. InfoPath初步扶助托管代码
  13. 十一分规的Outlook 托管插件

4、VSTO 3.0(VSTO 2008)

VSTO 3.0随同Visual Studio 2008发布:

金沙注册送58 20

对此Office化解方案开发来说,VSTO是简单但强硬的框架。那几个框架为每一种Office开发者带来了众多无不侧目的好处:窗体控件、类、安全性、服务器可度量性、面向对象特征、完整性、易宣布,等等。
1)、更安全的托管代码扩充
VSTO允许托管和非托管代码无缝地位于一起到平等的.NET程序集里,那允许开发者保留非托管代码而无须完全重写。带有链接或引用托管代码程序集的文书档案或工作簿被作为托管代码扩张。通过利用VSTO在Word或Excel中创制托管代码扩充,与宏相似但更安全。使用VSTO,能够创立仅必要装载数据的沙盘。
2)、数据缓存
数据缓存,容易地说,便是在内部存款和储蓄器中储存数据以便于赶快访问。Microsoft Office Word文档或Excel工作簿有三个隐身的控件,称之为运营时存款和储蓄控件(Runtime Storage Control),存款和储蓄缓存的数量。VSTO提供数据缓存成效,使用C#中的ServerDocument类,通过应用程序外部到Office来操控数据缓存,无须访问Word或Excel对象模型。
3)、自定义作用
选取可重复使用的类,VSTO 3.0提供极好的操纵来自定义Office应用程序。不像VBA开发者,VSTO开发者不囿于于VBA函数库。VSTO提供了一定普遍的类、对象和事件来创建Office商业消除方案。使用VSTO,开发者能够为Office应用程序自定义作用。这能够简单到在应用程序命令栏中充裕按钮或自定义职务窗格,或许复杂到用于访问分化数据源的数据报表模板。
4)、自定义用户界面
VSTO提供Windows窗体控件,扶助你为Office化解方案开发富用户界面(UI)。通过采取大量形形色色的控件集,VSTO开发者能够为用户成立丰盛的数码视图。每个和每类Windows窗体控件都有自已的特性、方法和事件设置,适合分歧的急需。
经过在文书档案和天职窗格里应用控件,VSTO使创办丰硕的用户界面更便于。例如,能够创立二个活跃的按钮命令发生套用信函。又如,纵然集团在其服务器上囤积了多少内容,用户在拍卖文书档案时想从服务器中引用一些内容还要不想离开当前编写的文档,使用VSTO可以使服务器内容在文书档案的任务窗格中可用而无须苦恼用户眼前的办事。
5)、智能标记
智能标记是Office应用程序可以在文档里识其余字符串。启用智能标记,Word试图识别文书档案中某类数据,通过朱红的点划线来显示。单击智能标记,出现一定数据类型的大概操作的列表。VSTO给Office开发者提供了对象模型,可用来为文书档案和工作簿创制智能标记。
6)、WPF支持
WPF能用于创制丰硕的、具有魔力的外观。在VSTO环境中可利用WPF。VSTO的可视设计器帮忙Windows窗体和WPF控件的利用。WPF为开创基于客户和依据网络的应用程序提供了牢靠的编制程序模型,并且在商务逻辑和UI之间显示清楚的分开。
7)、可视化的设计器
VSTO为Office应用程序提供了可视化的设计器,例如Word 200柒 、Excel 2007,展现在Visual Studio IDE里。在Visual Studio IDE里创造窗体只需拖动并放置窗体到Office文书档案中。开发者能够访问Visual Studio IDE中的许多工具和功用,例如智能感知、拖放控件和数据源。VSTO也提供了Ribbon可视化设计器,用于通过应用不难的.NET应用程序编制程序模型自定义Office成效区和编制程序。
8)、安全立异
VSTO安全模型包含从Office信任宗旨和Visual Studio Tools for
Office运营时的广大帮衬,补助缓解VBA代码平时涉及的平安题材。VBA安全模型有成都百货上千败笔,不难选用VBA开发许多病毒。为了安全地运营VBA宏,用户机器中务必设置安全性为高,并且应用数字签名。更重要的是,那个操作都急需用户手工业执行。在VSTO 3.0中,已经修改了平安模型。VSTO制造了安全策略,每一次创造工程时少不了在电脑中运作和调节和测试化解方案,在昭示前签名程序集。
9)、可维护性
为Office系统开发的VSTO消除方案更便于保险。更新已发表的消除方案,修改代码,以及更新单个的次第集将帮忙愈来愈多的能源在同样文书档案的八个副本里做一样的事体。全部代码将驻留在程序集里。在行使宏时,脚本驻留在Office文书档案里,无论曾几何时想翻新代码,必须修改每一个分包代码的文书档案。使用VSTO 3.0,能够通过简单地修改代码和翻新单个的次第集来管理应用程序级加载项,无须在同一文书档案的七个副本中做相同的事体。

VSTO 3.0**的新职能**
VSTO 3.0有所多量的新效用,也提升了现有的机要意义。上面列出在VSTO 3.0中可用的立异Office解决方案开发工作的一部分首要的新效率:

  • 文档次和级别的定制:文书档案级的定制是自定义驻留在单个文书档案里的消除方案。使用VSTO的文书档案级定制是新版VSTO中添加的重中之重意义之一。VSTO援助Word、Excel、Info帕特h的文书档案级化解方案。

     

  • 使用程序级加载项:应用程序级加载项被创建为托管代码程序集,当有关的Office应用程序运行时将装载应用程序级加载项。VSTO 3.0提供了直白编制程序访问.NET对象和控件。

 

  • 功能区可视化设计器:作用区是公司有关命令的新情势。实际上,它们当做控件显示。可视化设计器提供高档工具并帮忙更易于地创立和设计自定义作用区。

 

  • 职分窗格:任务窗格帮忙用户神速且更利于地访问音信。取决于用户的喜好,能够在Office应用程序用户界面中显得或隐蔽义务窗格。

  • 窗体区域:窗体区域是自定义标准的Outlook 二〇〇七用户界面包车型客车新办法。例如,在Visual Studio 二零一零中,VSTO 3.0提供了依照Windows窗体的统一筹划和付出环境。那允许Office开发者在单个的开发条件中执会调查总计局筹和编码新的Outlook窗体区域,将多数Windows窗体引入到Outlook的宿主环境中。

     

  • 工作流帮衬:VSTO提供可视化设计器接济开发者使用Visual Studio 2010创造工作流。三个向导选项用于成立工作流,并且一向将其赋值到发布地方。

 

  • SharePoint帮助:VSTO中的新对象援救开发者在Office应用程序中为SharePoint编制程序。能够应用VSTO增添Office客户端应用程序,使用SharePoint Portal将它们构成到公司缓解方案中,例如客户关系管理、供应链管理以及任何类似的应用程序。

  • 使用ClickOnce安排:ClickOcne陈设技术允许基于Windows应用程序使用最小程度的用户交互来布局和平运动行。安全区将范围使用ClickOnce技术布署的应用程序的准许和操作。

 

  • Word内容控件:内容控件是容器,其中能放置特定项指标剧情,例如日期、列表、图片或文本。

  • 富用户界面控件:能够创设带有足够且易于访问的用户界面包车型大巴Office解决方案。例如,能够创造带有Windows控件的职务窗格,和任何数据源交互数据。

 

  • 扶助别的的Office应用程序。

VSTO架构
VSTO应用程序由Office应用程序和.NET程序集组成。

  • Office应用程序:VSTO发表了指标,使之更易于编写Office应用程序。包蕴扩展应用程序和拍卖应用程序使用的数额的对象。要知道的根本之一是Word和Excel编辑器提供了Word或Excel文书档案视图。使用这个编辑器,能够编写制定和格式文书档案,就好像直接在Office应用程序中操作一样。

  • .NET程序集:包罗中间语言(IL)代码。描述程序的二进制消息的元数据存款和储蓄在内部存款和储蓄器中,是.NET程序集的一有的。除了元数据消息外,程序集也有称作Manifest的专门的公文。Manifest包蕴程序集当前版本的新闻。

VSTO架构的骨干零部件是文书档案级定制、应用程序级加载项和文书档案级的数据模型。VSTO的新架构允许编写和平运动作带有宏的Office应用程序。
金沙注册送58 21
上海体育地方片明Office 二零零七缓解方案逻辑架构。VSTO能够使Office开发者为InfoPath、Word和Excel文档成立文书档案级定制,而对此Outlook、PowerPoint和Visio,VSTO不协理文书档案级定制。
VSTO提供了格外好的面向对象编制程序协助。VSTO提供了对C#编制程序语言的完全扶助,允许在Office解决方案中履行面向对象编制程序。面向对象编制程序是一种软件编制程序情势,程序结构基于对象时期的相互,以执行职责。
VSTO的架构划设想计支持Office开发者完结了应用程序和数码的分离,提供开发使用程序级化解方案的增高协助,并且发表了三种对象使Office开发者更易于编写Office应用程序。开发应用程序级和文档级的缓解方案是VSTO中另一项架构革新。

开发格局
运用VSTO 3.0成立的缓解方案类型分成两类:文书档案级消除方案和动用程序级消除方案。
1)、面向文书档案的章程
面向文档的情势被尤其规划为接触Word或Excel文书档案的主导并带有原先设计的文书档案不帮助的音信。VSTO 3.0支撑面向文书档案的办法成立Word、Excel和InfoPath。实际上,面向文书档案的点子提供针对性13分特定任务的文书档案,不会潜移默化到文书档案驻留的应用程序。
2)、面向应用程序的艺术
VSTO 3.0独具为Office 2005套件中全体的应用程序创制面向应用程序的法子的力量。能够创立和施行向Office应用程序中添加了各类功用和特色的加载项。
VSTO**付出和安顿
VSTO系统3.0运维时,运行Office 二零零七化解方案的主要必要,被内置到VSTO中。而VSTO 3.0被平放到Visual Studio 2009设置中。
行使VSTO创造Office应用程序**
在Visual Studio 2010中席卷VSTO,也便是说,Microsoft第贰遍将Visual Studio 二〇〇九和VSTO 3.0绑在了一块。在VSTO 3.0中,Microsoft Office工具变得进一步强劲,因为Microsoft使Office开发环境对开发者更是温馨,通过创造新的开销条件救助开发者成立Office应用程序里的效能的消除方案。因而,Office开发者能够不难地创设化解方案,为他们的商务做越来越多干活儿,另一方面,重复使用Office应用程序中存活的可用功用,从而减资支出。
VSTO甚至能够整合现有的E卡宴P系统,增加集团的成才。能够选择VSTO扩张Office客户端应用程序,将VSTO与SharePoint Portal整合来提供集团化解方案,例如Office商务应用程序,包涵客户关系管理、供应链管理,等等。

壹 、VSTO开发环境
VSTO 3.0不是单身的安装包,当安装Visual Studio 二〇〇九时,VSTO 3.0将与任何的框架和所需的零件一起安装。
2、包(Package)
当安装Microsoft VSTO 3.0分发包时设置VSTO运转时。VSTO 3.0分发包是将Visual Studio 二〇一〇和.NET框架的成效和生产力带给建立在Office 二〇〇五应用程序中的商务消除方案的框架。
金沙注册送58 22
上海体育地方表达了VSTO的本子历史,以及各版本之间的部分主要的不如。当前版本的VSTO仅补助理编辑程语言VB.NET和C#。咱们希望VSTO的下三个本子能支撑任何的编制程序语言。

3、Visual Studio整合
为了不难创造定制的用户界面,VSTO 3.0在Visual Studio里提供了Office应用程序的可视化表现。VSTO 3.0很好地与Visual Studio 2010整合在一起,为Office开发者提供了整机的开发和配置Office化解方案的工具。Visual Studio 2010力所能及使开发者制造可升级的Office商务应用程序、改变重要的Office UI特征、辅助理工科程师作流、以及开创更易于的布置。
下面,看看Visual Studio 2009中Office 二〇〇七应用程序的高人一等的VSTO项目模板。
金沙注册送58 23
Visual Studio 二〇〇九早就打包了使用VSTO创设Office消除方案所急需的全体VSTO 3.0零部件。当安装Visual Studio 二〇〇八时,全部相关的安装,蕴含VSTO 3.0的花色模板、Office开发引用和其余组件,都被设置并完全结合到新的Visual Studio 二零一零开发条件中。

 

肆 、创设VSTO化解方案
在支付和传递创新的Microsoft技术方面,Visual Studio 二零零六是13分快捷、协同性好和灵活的,包蕴提升的言语和数目功效。Office 二零零七中支持的C#和VB.NET是增加的言语特色之一,并且简单与别的数据源交互数据,例如Microsoft SQL服务器,是多少个性之一。这几个特点确定保证开发者能够火速地创制连接的应用程序,传递下一代软件实施,以及制服应用程序软件开发搦战。
金沙注册送58 24
上海体育场面呈现了Office消除方案的开发条件。在图中,客户端代表开发环境机器,在Visual Studio 二〇一〇内部的VSTO 3.0代表VSTO整合在Visual Studio中,Office 二零零六客户端工具是Office应用程序,包括Word、Excel、Info帕特h等,应该棉被服装置在客户端机器上。
选拔Visual Studio 二零一零支付环境能够创造应用程序级、数据宗旨化解方案。数据主题化解方案是汇总于数据操作和数码存款和储蓄的成效。
Visual Studio 二〇〇九支出条件使得开发带有首要的Office 二零零五系统本性设计时和平运动转时匡助的消除方案化为恐怕,例如功效区、自定义任务窗格、文书档案级化解方案、Outlook窗体区域,等等。
成效区是Office应用程序中显示菜单项的新点子。在新开发条件中,有可视化设计器,能够拖拉功效区里的控件,简单设计自定义的作用区菜单。甚至数据有关的操作,例如创造数量连接,有数据连接向导不难成立数量连接。
在创建的Office项目化解方案中,能够见到列出的引用,例如System.AddIn、System.Core等等,它们被活动装载作为项目模块的一局地。那使得开发者更易于初始编程,不需求像此前一样手工业添加引用和表明化解方案。
经过利用基于XML的数码/视图分离和编制程序性,Office开发者能够将商务数据整合到文书档案里。

5、查看IDE窗口
Visual Studio是一款极其卓绝的成品,专门为开发者设计,是开发者最常使用的开发工具之一,内置有IDE,能够使开发者使用Microsoft技术创立差别档次的应用程序。日常,IDE由源代码编辑器、编写翻译器和调节和测试器组成。暗中认可景况下,Microsoft Visual Studio
IDE提供智能感知、调节和测试、编写翻译、访问控件、以及开创化解方案的能力。最新增强了功效区设计器、拖放控件、并为Office应用程序增强了调节功用,缩减了付出时间,进步了开发者的频率。
放手的VSTO对象模型被设计来帮忙.NET,许多常用的作用被打包且很好地整合了。在新本子中,诸如Word、Excel和InfoPath的对象窗口工具被直接整合到IDE界面里,支持Office开发者无须对象模型的高级知识就能成立消除方案。对于Word 二零零六和Excel 二零零五,VSTO在Visual Studio IDE中也有可视化设计器。
金沙注册送58 25
上图中,能够见到Visual Studio 二零零六中怎么着呈现Excel 二零零五可视化设计器。同样,Visual Studio 2010 IDE也提供了可视化功效区设计器,允许Office开发者使用拖放界面来设计功用区,使用正式的.NET代码与作用区交互。
金沙注册送58 26
上航海用教室显示Office消除方案开发里功用区的可视化设计器,通过提供拖放控件和不难访问财富,简化了成效区开发进程。同样,Visual Studio 二〇〇九简化并加快了操作窗格、内定文书档案的职责窗格、成立钦定应用程序的自定义职分窗格以及Outlook窗体区域设计器的花费进程。

6、调试
调节是软件开发中最重视的任务之一,并且是独具开发者在他们的开销进程中会碰着重重次的一项职务。在Visual Studio IDE中,开发者为调节和测试.NET应用程序有二种可用的调剂采取。
Visual Studio 2009为使用VSTO 3.0的Office化解方案开发提供了一组强大的创办和调节工具,与VSTO 2.0对待是一项大的修正。在开立布局时,开发者能够选用他们想创建的机件,排除他们近来想制止创建的零件。开发者能够像项目一律,灵活地为化解方案创制布局。

 

大家期待下一版本能带来哪些?
依据作者的辨析和作为一名VSTO开发者的经验,大家期望下一版本的VSTO:

  • 目前,VSTO 3.0支持VB.NET和C#支出Office消除方案。在以后的VSTO版本中,大家希望扶助任何语言,例如C++,那将辅助C++开发者制造VSTO消除方案。
  • VSTO 3.0智能标记仅限于Office应用程序中文档次和级别化解方案,不可能在应用程序级化解方案中利用,由此大家期望Microsoft在以往的VSTO版本中添加那项成效。
  • 选取VSTO和Visual Studio环境在Office应用程序内成立工作流活动是我们在下一本子中希望的功能。数据和应用程序协同工作的能力是Windows工作流的主导,在VSTO中的立异将帮扶我们重新协会见向工作流的支付。
  • 应该在今后的版本中在Visio应用程序中也丰裕应用VSTO创制文书档案级的自定义义务窗格的功效。那将对Visio用户管理自定义形状是一蹴而就的。

5、VSTO 4.0(VSTO
2010)

虽说今后VSTO 4.0还尚无专业发布,不过从测试版已经足以见见些端倪:

  1. 对61位Office 二〇一〇支出的援助
  2. 折叠工具栏项目支持
  3. C# 4.0 、.net framework 4.0支持
  4. 3遍针对全部用户陈设Office项目
  5. 在单个包中安顿八个Office项目
  6. 配备完Office项目后还能够实施附加操作

 

肆 、Office开发存在的难点

    由于历史遗留难题,Office本来是设计与COM协同工作的,那就使得从一初步VSTO就有点”水土不服”。.net代码通过封装COM与Office通讯,不过有时那种合营却并不和谐,Office对象模型并不三番五次遵从.net设计所采纳的命名规则和设计方式。

五、Visual Basic的”优势”

    在C# 4.0发表以前(尽管未来也未曾公布),用VB开发Office比用C#有利的多,那是因为VB简化了对Office对象模型的调用方法。但是随着C# 4.0的就要宣告,VB的这种”优势”将会变得越来越小。园子里有不少人曾经写过C# 4.0的新特色,那里仅领到出针对于COM操作的立异:

金沙注册送58 27

Improved COM
Interoperability

在C#中在调用COM对象如office对象时,日常必要写一堆不供给的参数:

object fileName = "Test.docx";

 

object missing  = System.Reflection.Missing.Value;

 

doc.SaveAs(ref fileName,

 

ref missing, ref missing, ref missing,

 

ref missing, ref missing, ref missing,

 

ref missing, ref missing, ref missing,

 

ref missing, ref missing, ref missing,

 

ref missing, ref missing, ref missing);

 

4.0中就足以平昔写成:

doc.SaveAs("Test.docx");

 

C#4.0对COM交互做了上面4个人置的改良:

Automatic object -> dynamic
mapping (自动类型转换)

Optional and named parameters
(可选命名参数)

Indexed properties (索引属性?)

Optional “ref” modifier
(可选 ref 修饰)

Interop type embedding (“No PIA”)
(主调程序集嵌入)

对第3点和第⑥点的简要解释如下:

在COM调用中,很多输入输出类型都是object,那样就非得清楚重回对象的适用品种,强制转换后才得以调用相应的主意。在4.0中有了dynamic的支持,就足以在导入这个COM接口时将变量定义为dynamic而不是object,省掉了强制类型转换。

PIA(Primary Interop
Assemblies)是根据COM API生成的.Net Assembly,一般体量相比较大。在4.0中运作时不供给PIA的留存,编写翻译器会判定你的程序具体行使了哪一部分COM API,只把那有个别用PIA包装,直接进入到你协调程序的Assembly里面。

⑥ 、开发工具

一 、Office 2006 Enterprise 艾德ition With
SP2或更新版本

② 、Visual Studio 二零零六 Team System With
SP1 或更新版本

3、OpenXML SDK 2.0

柒 、推荐能源

① 、书籍:《VSTO 开发指南》,VSTO的独尊小说,强烈推荐。

2、网站:

1)MSDN VSTO版块    

2)两位VSTO大师的博客,也是《VSTO 开发指南》的联协笔者:

Eric Carter    Eric
Lippert

3)Office
贰零零玖法定博客

八、VSTO 4.0 Hello World

终极,让大家用三个实例来终止此次研商:)

一 、新建2个Office 二〇一〇的Excel Workbook项目:

金沙注册送58 28

二 、在工作簿中添加三个按钮,添加一个Click事件:

金沙注册送58 29

③ 、弹出欢迎音信”

金沙注册送58 30

四 、全体保留,F5运维:

金沙注册送58 31

多个最简单易行的VSTO 4.0门类就大功告成了。

 

九、小结:

    这一次钻探成本了大气篇幅讲述了VSTO的历史变动及其历代版本中的增强作用,后续篇章会注意研商各职能的具体贯彻。本次的示范分外基本,基本得以忽略,可是却包括了创立1个完整的VSTO项目标百分之百步骤,后续练习将会在此基础上进展扩充,实现部分高等功能。

相关文章

网站地图xml地图