威尼斯人线上娱乐

的各类方法计算,VSTO学习笔记

29 3月 , 2019  

温馨在用的Excel操作类,因为每每在工作中要操作Excel文件,然则使用vba达成起来其实是不便利,而且编写也很费力,拼接3个字符串都看的头昏眼花。

C# 导出 Excel 的种种情势计算,

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

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

威尼斯人线上娱乐 1

威尼斯人线上娱乐 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
威尼斯人线上娱乐 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

首先种办法品质实在是不敢恭维,而且局限性太多。首先必供给安装
office(假如总结机方面没有的话),而且导出时索要钦赐文件保留的门道。也得以输出到浏览器下载,当然前提是现已保存写入数据。

 

第二种:使用 Aspose.Cells.dll

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

能够参见:

威尼斯人线上娱乐 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
威尼斯人线上娱乐 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 三千 及以上版本;Excel 12.0
针对 Excel 二零零七 及以上版本。

HD帕杰罗:Yes 表示第贰行蕴涵列名,在总计行数时就不带有第3行。NO 则统统相反。

IMEX:0 写入方式;1 读取形式;2 读写格局。假设报错为“不可能修改表 sheet1
的统一筹划。它在只读数据库中”,那就去掉那些,难题消除。

威尼斯人线上娱乐 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
威尼斯人线上娱乐 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()
方法另存为一下,这样质量也就更差了。

动用操作命令创立的表都以在终极面包车型客车,前边的也无奈删除(笔者是没有找到方法),当然也能够不再成立,直接写入数据也得以。

的各类方法计算,VSTO学习笔记。 

第四种:NPOI

NPOI 是 POI 项目标.NET版本,它不应用 Office COM 组件,不必要安装
Microsoft Office,最近只支持 Office 97-二〇〇四 的文件格式。

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

威尼斯人线上娱乐 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
威尼斯人线上娱乐 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 二零零一 及以下版本,所以不能导出 .xlsx 格式的
Excel 文件。不过那种格局品质不错,而且操作方便。

 

导出 Excel 的种种艺术总计, 第1种:使用
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
Services)上下载Excel到本地打开,用户编辑后再上传回服务器端。当时工期殷切,目前查了些资料,用VSTO

其最近候C#出现了,发现使用C#来操作Excel非凡方便,比VBA不知道高到哪里去了,而且直接就能够上手,所以笔者就把常用的一对操作封装成了3个类,编写翻译成DLL方便在相继门类中调用。

一 、PDF的预览和操作

在较早的DevExpress的控件里面,已经提供了对应的PDF文书档案的来得控件,不过出于其对PDF格式帮忙不是很好,有个别文书档案是Office导出的,也不是很正规阅读,由此很少使用,本文介绍的DevExpress的PDF查看控件是根据14.1的,测试过众多文书档案,好像都能健康打开,由此也想在系统中普遍选拔了。

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

威尼斯人线上娱乐 10

为了展现PDF文书档案,大家须求在界面里面添加一个XtraPdfViewer.PdfViewer的控件,那几个第③是用来突显PDF的,它有许多品质方法,用来兑现对PDF的拍卖操作,测试界面设计好如下所示。

威尼斯人线上娱乐 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对象实现相关的操作了。

 

  • Excel COM
    API成功。正因为这一个项目,小编发觉了VSTO的无敌功能与潜力,决定抽出部分时光来出彩钻研下。

实则采纳第3方控件也得以完结相应的作用,而且一些控件也是应用Visual
Studio Tools for Office
(VSTO)中一样风格的接口,直接就足以上手,然而好用的都以要付钱的。那里不做研究。

② 、WOCR-VD文书档案的预览和操作

类似于PDF文书档案,大家对WO奥迪Q5D文书档案,也是通过运用Rich艾德itControl达成文书档案的显得,不过和PDFViewer区别,这些控件能够达成对文书档案的改动和封存操作,这种对于大家提供用户对文书档案举行编制很方便。

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

威尼斯人线上娱乐 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();
        }
    }

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

威尼斯人线上娱乐 13

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

威尼斯人线上娱乐 14

然而话说回来,那么些Rich艾德itControl纵然能够较好展现Word文书档案,可是也有一些字体展现的不是很好,格式和微软的Word软件展现的某个不太一样,格式有所损失。

因此一旦对于格式要求相比较小心的,建议照旧只是做体现为佳,不要保存原有的文书档案。假若对格式不是专程严酷,倒是能够用作一个文书档案服务器达成文书档案的新建、保存处理。

 

以身作则代码下载

 

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

对于Excel文档的预览和操作,DevExpress控件在近年来版本中加进的XtraSpreadsheet.SpreadsheetControl控件就足以兑现Excel的显得和处理操作,这些控件很强劲,可以拍卖很复杂格式的Excel文书档案,就算笔者原先选拔了其余一个FarPoint
Spread控件组,可是那几个XtraSpreadsheet控件组,要是集成在DevExpress也就很有利了。

威尼斯人线上娱乐 15

这些DevExpress的控件,能够在其间实行Excel的新建、保存、打印预览等操作,当然也能够打开我们已有的Excel文件了。

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

威尼斯人线上娱乐 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的预览操作看似。

威尼斯人线上娱乐 17

 

上述正是多少个常用文书档案的来得和操作案例,有了那么些我们很不难整合到大家的附属类小部件管理内部了。

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

威尼斯人线上娱乐 18

 

本体系具有示例代码均在 Visual Studio 二零一零 Beta 2 + Office 二零一零 Beta
下测试通过 

先是要添加程序集引用:Microsoft.Office.Interop.Excel,因为大家使用的是OFFICE贰零壹陆,所以选取15.0.0.0本子。

 

威尼斯人线上娱乐 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
2001,即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 贰零零陆生产,提供了大气新特点:

  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发布:

威尼斯人线上娱乐 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使创办丰裕的用户界面更易于。例如,可以创制2个活蹦乱跳的按钮命令产生套用信函。又如,假如公司在其服务器上囤积了数码内容,用户在拍卖文书档案时想从服务器中援引一些剧情还要不想离开当前编辑的文书档案,使用VSTO能够使服务器内容在文书档案的天职窗格中可用而无须干扰用户如今的行事。
5)、智能标记
智能标记是Office应用程序能够在文书档案里识其他字符串。启用智能标记,Word试图识别文书档案中某类数据,通过海洋蓝的点划线来体现。单击智能标记,出现一定数据类型的可能操作的列表。VSTO给Office开发者提供了指标模型,可用来为文书档案和工作簿创制智能标记。
6)、WPF支持
WPF能用于创设丰裕的、具有吸重力的外观。在VSTO环境中可采取WPF。VSTO的可视设计器援救Windows窗体和WPF控件的选用。WPF为开创基于客户和依照网络的应用程序提供了牢靠的编制程序模型,并且在商务逻辑和UI之间显示清楚的诀别。
7)、可视化的设计器
VSTO为Office应用程序提供了可视化的设计器,例如Word 200⑦ 、Excel 二零零七,展现在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存有多量的新效用,也增进了现有的第2功用。上面列出在VSTO 3.0中可用的改正Office消除方案开发工作的某个最重要的新作用:

  • 文书档案级的定制:文书档案级的定制是自定义驻留在单个文书档案里的消除方案。使用VSTO的文书档案级定制是新版VSTO中添加的最重要意义之一。VSTO扶助Word、Excel、InfoPath的文书档案级化解方案。

     

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

 

  • 作用区可视化设计器:成效区是组织有关命令的新措施。实际上,它们当做控件呈现。可视化设计器提供高档工具并协理更便于地开创和设计自定义功效区。

 

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

  • 窗体区域:窗体区域是自定义标准的Outlook 二〇〇六用户界面包车型地铁新章程。例如,在Visual Studio 二〇〇八中,VSTO 3.0提供了基于Windows窗体的设计和开销环境。那允许Office开发者在单个的支出条件中陈设和编码新的Outlook窗体区域,将多数Windows窗体引入到Outlook的宿主环境中。

     

  • 工作流补助:VSTO提供可视化设计器支持开发者使用Visual Studio 2009创立工作流。四个向导选项用于创立工作流,并且直接将其赋值到公布地方。

 

  • 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应用程序。
威尼斯人线上娱乐 21
上图片明Office 2006化解方案逻辑架构。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。实际上,面向文书档案的艺术提供针对性十二分特定职务的文书档案,不会影响到文书档案驻留的应用程序。
2)、面向应用程序的法子
VSTO 3.0富有为Office 贰零零柒套件中负有的应用程序创建面向应用程序的法门的力量。能够创建和实践向Office应用程序中添加了各样作用和特色的加载项。
VSTO**支出和配置
VSTO系统3.0运转时,运营Office 二零零六化解方案的重点需要,被平放到VSTO中。而VSTO 3.0被安置到Visual Studio 二〇一〇设置中。
使用VSTO创制Office应用程序**
在Visual Studio 2009中包含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 二〇〇六应用程序中的商务消除方案的框架。
威尼斯人线上娱乐 22
上海教室表达了VSTO的本子历史,以及各版本之间的有个别主要的分裂。当前版本的VSTO仅支持理编辑程语言VB.NET和C#。我们盼望VSTO的下3个版本能协助别的的编制程序语言。

3、Visual Studio整合
为了便于创立定制的用户界面,VSTO 3.0在Visual Studio里提供了Office应用程序的可视化表现。VSTO 3.0很好地与Visual Studio 二零零六整合在一起,为Office开发者提供了总体的费用和配备Office解决方案的工具。Visual Studio 二零一零可见使开发者创制可提高的Office商务应用程序、改变首要的Office UI特征、协助理工科程师作流、以及开创更便于的布局。
下边,看看Visual Studio 2009中Office 2005应用程序的独立的VSTO项目模板。
威尼斯人线上娱乐 23
Visual Studio 2010早就打包了动用VSTO创制Office化解方案所急需的满贯VSTO 3.0零部件。当安装Visual Studio 二〇一〇时,全数相关的安装,包涵VSTO 3.0的门类模板、Office开发引用和其他组件,都被设置并完全结合到新的Visual Studio 二〇一〇付出条件中。

 

肆 、创造VSTO解决方案
在支付和传递立异的Microsoft技术上边,Visual Studio 2010是老大高效、协同性好和灵活的,包涵提升的言语和数码作用。Office 2005中支持的C#和VB.NET是增加的语言特征之一,并且不难与其它数据源交互数据,例如Microsoft SQL服务器,是数据天性之一。那个特征确认保障开发者能够高效地创设连接的应用程序,传递下一代软件推行,以及制伏应用程序软件开发挑衅。
威尼斯人线上娱乐 24
上航海用教室显示了Office化解方案的付出环境。在图中,客户端代表开发条件机器,在Visual Studio 二〇一〇内部的VSTO 3.0意味着VSTO整合在Visual Studio中,Office 二零零七客户端工具是Office应用程序,包含Word、Excel、InfoPath等,应该被安装在客户端机器上。
动用Visual Studio 二〇〇八成本环境能够创立应用程序级、数据基本化解方案。数据主导消除方案是集中于数据操作和多少存款和储蓄的效果。
Visual Studio 二零零六开支环境使得开发带有首要的Office 2006系统性情设计时和周转时帮忙的消除方案变成恐怕,例如功用区、自定义职责窗格、文书档案级化解方案、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 2006和Excel 二〇〇七,VSTO在Visual Studio IDE中也有可视化设计器。
威尼斯人线上娱乐 25
上海图书馆中,能够看来Visual Studio 二零一零中怎么样展现Excel 2005可视化设计器。同样,Visual Studio 二〇〇九 IDE也提供了可视化功用区设计器,允许Office开发者使用拖放界面来设计成效区,使用正规的.NET代码与效用区交互。
威尼斯人线上娱乐 26
上海体育场面突显Office解决方案开发里功效区的可视化设计器,通过提供拖放控件和不难访问能源,简化了成效区开发进度。同样,Visual Studio 二〇一〇简化并加快了操作窗格、钦定文书档案的义务窗格、创立指定应用程序的自定义职责窗格以及Outlook窗体区域设计器的支付进度。

6、调试
调节是软件开发中最重庆大学的职分之一,并且是有着开发者在他们的支出进度中会碰到重重次的一项任务。在Visual Studio IDE中,开发者为调节和测试.NET应用程序有二种可用的调节和测试采取。
Visual Studio 二〇〇九为运用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. 对60位Office 2009付出的援助
  2. 折叠工具栏项目协理
  3. C# 4.0 、.net framework 4.0支持
  4. 一次针对全体用户安顿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操作的核对:

威尼斯人线上娱乐 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交互做了上边几上边的寻行数墨:

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

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

Indexed properties (索引属性?)

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

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

对第③点和第五点的不难表达如下:

在COM调用中,很多输入输出类型都是object,那样就务须掌握重回对象的适宜品种,强制转换后才得以调用相应的措施。在4.0中有了dynamic的帮忙,就足以在导入这么些COM接口时将变量定义为dynamic而不是object,省掉了勒迫类型转换。

PIA(Primary Interop
Assemblies)是依照COM API生成的.Net Assembly,一般容量相比较大。在4.0中运维时不供给PIA的留存,编写翻译器会咬定你的次序具体运用了哪部分COM API,只把这某个用PIA包装,直接参加到您协调程序的Assembly里面。

6、开发工具

壹 、Office 二〇〇七 Enterprise 艾德ition With
SP2或更新版本

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

3、OpenXML SDK 2.0

7、推荐财富

壹 、书籍:《VSTO 开发指南》,VSTO的显要文章,强烈推荐。

2、网站:

1)MSDN VSTO版块    

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

Eric Carter    Eric
Lippert

3)Office
贰零零捌官方博客

八、VSTO 4.0 Hello World

最后,让我们用叁个实例来终结本次研讨:)

壹 、新建1个Office 二〇〇九的Excel Workbook项目:

威尼斯人线上娱乐 28

② 、在工作簿中添加八个按钮,添加2个Click事件:

威尼斯人线上娱乐 29

3、弹出欢迎音讯”

威尼斯人线上娱乐 30

④ 、全体保留,F5运维:

威尼斯人线上娱乐 31

2个最简单易行的VSTO 4.0类型就成功了。

 

九、小结:

    这一次钻探费用了大气篇幅叙述了VSTO的野史转变及其历代版本中的增强效能,后续篇章会注意商讨各职能的现实贯彻。这次的演示拾叁分基本,基本能够忽略,可是却包涵了创设一个全部的VSTO项目标万事手续,后续演练将会在此基础上拓展扩张,达成部分尖端功用。


相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图