数据字典生成工具之旅(4):NPOI操作EXECL

这篇会介绍NPOI读写EXECL,读写EXECL的组件很多,可以使用微软自己的COM组件EXECL.exe读写,不过这种方式限制很大。

1:客户环境必须装Office(虽然现在机子上不装Office的几乎没有吧)

2:EXECL读写完毕后EXECL还有进程还留在后台  ,内存回收不了

基于以上的原因,就采用了开源组件NPOI进行操作了。

阅读目录

  • NPOI简介
  • 简单示例
  • NPOI在本工具的使用及总结
  • 工具源代码下载
  • 学习使用

回到顶部

NPOI简介

1.Excel表格叫做工作表:WorkBook(工作薄),包含的叫页(工作表):Sheet;行:Row;单元格Cell。

2.Npoi 下载地址:http://npoi.codeplex.com

3.Npoi 学习系列教程推荐:http://tonyqus.sinaapp.com

4.npoi 能够读写几乎所有的Office 97-2010文件格式(特别提示读取EXECL2007版本及以上的需要使用NPOI2.0版本才行,也就是.xlsx。之前EXECL老版本是.xls),至少能够支持Word, PowerPoint, Excel, Visio的格式。

回到顶部

简单示例

        1.创建一个简单的xls文件

//创建xls文件
        private void button1_Click(object sender, EventArgs e)
        {
            //创建工作薄
            HSSFWorkbook wk = new HSSFWorkbook();
            //创建一个名称为mySheet的表
            ISheet tb = wk.CreateSheet("mySheet");
            //创建一行,此行为第二行
            IRow row = tb.CreateRow(1);
            for (int i = 0; i < 20; i++)
            {
                ICell cell = row.CreateCell(i);  //在第二行中创建单元格
                cell.SetCellValue(i);//循环往第二行的单元格中添加数据
            }
            using (FileStream fs = File.OpenWrite(@"c:/myxls.xls")) //打开一个xls文件,如果没有则自行创建,如果存在myxls.xls文件则在创建是不要打开该文件!
            {
                wk.Write(fs);   //向打开的这个xls文件中写入mySheet表并保存。
                MessageBox.Show("提示:创建成功!");
            }
        }

2.读取简单的xls文件

/// <summary>
        /// 读取一个简单xls文件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button2_Click(object sender, EventArgs e)
        {
            StringBuilder sbr = new StringBuilder();
            string path = GetDeskTopPath() + @"\myxls.xls";
            using (FileStream fs = File.OpenRead(path))   //打开myxls.xls文件
            {
                HSSFWorkbook wk = new HSSFWorkbook(fs);   //把xls文件中的数据写入wk中
                for (int i = 0; i < wk.NumberOfSheets; i++)  //NumberOfSheets是myxls.xls中总共的表数
                {
                    ISheet sheet = wk.GetSheetAt(i);   //读取当前表数据
                    for (int j = 0; j <= sheet.LastRowNum; j++)  //LastRowNum 是当前表的总行数
                    {
                        IRow row = sheet.GetRow(j);  //读取当前行数据
                        if (row != null)
                        {
                            sbr.Append("-------------------------------------\r\n"); //读取行与行之间的提示界限
                            for (int k = 0; k <= row.LastCellNum; k++)  //LastCellNum 是当前行的总列数
                            {
                                ICell cell = row.GetCell(k);  //当前表格
                                if (cell != null)
                                {
                                    sbr.Append(cell.ToString());   //获取表格中的数据并转换为字符串类型
                                }
                            }
                        }
                    }
                }
            }
            sbr.ToString();
            path = GetDeskTopPath() + @"\myText.txt";
            using (StreamWriter wr = new StreamWriter(new FileStream(path, FileMode.Append)))  //把读取xls文件的数据写入myText.txt文件中
            {
                wr.Write(sbr.ToString());
                wr.Flush();
                MessageBox.Show("提示:写入成功!");
            }
        }

3.读取EXECL文件,兼容xls和xlsx文件,NPOI2.0特意为这种情况提供接口读取,免去用户需要判断文件格式写不同代码的烦恼,看下面的实例

 StringBuilder sbr = new StringBuilder();
            string path = GetDeskTopPath() + @"\myxls.xls";
            using (FileStream fs = File.OpenRead(path))   //打开myxls.xls文件
            {
                IWorkbook wk = WorkbookFactory.Create(fs);   //使用接口,自动识别excel2003/2007格式
                for (int i = 0; i < wk.NumberOfSheets; i++)  //NumberOfSheets是myxls.xls中总共的表数
                {
                    ISheet sheet = wk.GetSheetAt(i);   //读取当前表数据
                    for (int j = 0; j <= sheet.LastRowNum; j++)  //LastRowNum 是当前表的总行数
                    {
                        IRow row = sheet.GetRow(j);  //读取当前行数据
                        if (row != null)
                        {
                            sbr.Append("-------------------------------------\r\n"); //读取行与行之间的提示界限
                            for (int k = 0; k <= row.LastCellNum; k++)  //LastCellNum 是当前行的总列数
                            {
                                ICell cell = row.GetCell(k);  //当前表格
                                if (cell != null)
                                {
                                    sbr.Append(cell.ToString());   //获取表格中的数据并转换为字符串类型
                                }
                            }
                        }
                    }
                }
            }
            sbr.ToString();
            path = GetDeskTopPath() + @"\myText.txt";
            using (StreamWriter wr = new StreamWriter(new FileStream(path, FileMode.Append)))  //把读取xls文件的数据写入myText.txt文件中
            {
                wr.Write(sbr.ToString());
                wr.Flush();
                MessageBox.Show("提示:写入成功!");
            }

上面表红部分是读取文件的接口,需要着重注意。NPOI提供WorkbookFactroy工厂类。另外创建xlxs文件方法类似,唯一区别使用XSSFWorkbook创建WorkBook对象。

XSSFWorkbook wk = new XSSFWorkbook();

回到顶部

NPOI在本工具的使用及总结

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.IO;
using NPOI.HSSF.UserModel;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;

namespace MyTools.DataDic.Utils
{
    /// <summary>
    /// 解析Execl文件,读取信息
    /// </summary>
    public class ExeclReader : IReader
    {
        /// <summary>
        /// Execl文件路径
        /// </summary>
        private string _pdmPath;

        private List<TableInfo> mTables = null;

        private IWorkbook hssfworkbook = null;

        /// <summary>
        /// 校验文件路径是否存在
        /// </summary>
        /// <param name="pdmPath">EXECL文件路径</param>
        private void CheckPath(string pdmPath)
        {
            if (string.IsNullOrEmpty(pdmPath))
            {
                throw new Exception("文件路径不能为空!");
            }
            if (!pdmPath.EndsWith(".xls", true, null) && !pdmPath.EndsWith(".xlsx", true, null))
            {
                throw new Exception("文件格式不正确,请选择EXECL文件!");
            }
            if (!File.Exists(pdmPath))
            {
                throw new Exception("指定文件不存在!");
            }
        }

        /// <summary>
        /// 构造函数 根据路径生成所有表的SQL
        /// </summary>
        /// <param name="pdmPath">EXECL文件路径</param>
        public ExeclReader(string pdmPath)
        {
            try
            {
                CheckPath(pdmPath);
                _pdmPath = pdmPath;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// 初始化EXECL
        /// </summary>
        /// <returns>HSSFWorkbook</returns>
        private IWorkbook InitHSSFWorkbook()
        {
            if (hssfworkbook == null)
            {
                try
                {
                    using (FileStream fs = new FileStream(_pdmPath, FileMode.Open, FileAccess.Read))
                    {
                        hssfworkbook = WorkbookFactory.Create(fs);
                    }
                }
                catch (Exception e)
                {
                    throw e;
                }
            }
            return hssfworkbook;
        }

        /// <summary>
        /// 从EXECL读取表信息
        /// </summary>
        /// <returns> List</returns>
        public List<TableInfo> GetTableInfo()
        {
            try
            {
                IWorkbook hssfworkbook = InitHSSFWorkbook();
                List<TableInfo> Tables = new List<TableInfo>();
                //杜冬军2014-05-03修改 循环读取EXECL所有的非隐藏Sheet
                //sheet总数
                int iSheetNum=hssfworkbook.NumberOfSheets;
                ISheet sheet = null;
                for (int m = 0; m < iSheetNum; m++)
                {
                    if (hssfworkbook.IsSheetHidden(m))
                    {
                        continue;
                    }
                    sheet = hssfworkbook.GetSheetAt(m);
                    IRow row = null;
                    ICell cell = null;
                    int iLastRowNum = sheet.LastRowNum;
                    for (int i = 0; i < iLastRowNum; i++)
                    {
                        row = sheet.GetRow(i);
                        if (row == null)
                        {
                            continue;
                        }
                        for (int j = 0; j < row.LastCellNum; j++)
                        {
                            //列索引异常BUG修复 2014-06-07杜冬军修改 row.Cells不适合
                            cell = row.GetCell(j);
                            if (cell != null && cell.ToString().Trim() == "数据表中文名称")
                            {
                                i = GetTable(sheet, i, cell.ColumnIndex, Tables, sheet.SheetName.Trim());
                                break;
                            }
                        }
                    }
                }
                mTables = Tables;
                return Tables;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// 从中读取物理图信息
        /// </summary>
        /// <returns> List</returns>
        public List<PhysicalDiagramInfo> GetPDInfo()
        {
            try
            {
                List<PhysicalDiagramInfo> PDList = new List<PhysicalDiagramInfo>();
                IWorkbook hssfworkbook = InitHSSFWorkbook();
                if (mTables == null)
                {
                    mTables = GetTableInfo();
                }
                PhysicalDiagramInfo pdInfo = new PhysicalDiagramInfo();
                string pid = System.Guid.NewGuid().ToString();
                pdInfo.Id = pid;
                pdInfo.Name = "所有数据";
                PDList.Add(pdInfo);

                int iSheetNum=hssfworkbook.NumberOfSheets;
                for (int m = 0; m < iSheetNum; m++)
                {
                    if (hssfworkbook.IsSheetHidden(m))
                    {
                        continue;
                    }
                    PhysicalDiagramInfo pd = new PhysicalDiagramInfo();
                    string pid1 = System.Guid.NewGuid().ToString();
                    pd.Id = pid1;
                    pd.Name = hssfworkbook.GetSheetAt(m).SheetName.Trim();
                    pd.PhyParentId = pid;
                    PDList.Add(pd);
                    List<TableInfo> query = (from a in mTables
                                                   where a.PDName == pd.Name
                                                   select a).ToList<TableInfo>();

                    foreach (TableInfo t in query)
                    {
                        pd = new PhysicalDiagramInfo();
                        pd.Id = System.Guid.NewGuid().ToString();
                        pd.Name = t.Code;
                        pd.IfEnd = true;
                        pd.PhyParentId = pid1;
                        PDList.Add(pd);

                    }
                }
                return PDList;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// 获取表信息
        /// </summary>
        /// <param name="tableName">表名</param>
        /// <returns>表信息</returns>
        public List<TableInfo> GetTableColumnName(string tableName)
        {
            if (string.IsNullOrEmpty(tableName))
            {
                throw new Exception("参数空异常!");
            }
            List<TableInfo> list = GetTableInfo();
            if (list != null && list.Count > 0)
            {
                IEnumerable<TableInfo> query =
                                 from c in list
                                 where c.Code == tableName
                                 select c;
                return query.ToList<TableInfo>();
            }
            return null;
        }

        /// <summary>
        /// 获取节点中表的信息
        /// </summary>
        /// <param name="sheet">sheet</param>
        /// <param name="iRow">iRow</param>
        /// <param name="iCell">iCell</param>
        /// <param name="sheetName">sheetName</param>
        /// <returns>表信息</returns>
        private int GetTable(ISheet sheet, int iRow, int iCell, List<TableInfo> Tables,string sheetName)
        {
            try
            {
                TableInfo mTable = new TableInfo();
                List<ColumnInfo> list = new List<ColumnInfo>();
                List<PkKeyInfo> listPkKeyInfo = new List<PkKeyInfo>();
                mTable.ListColumnInfo = list;
                mTable.ListPkKeyInfo = listPkKeyInfo;
                mTable.PDName = sheetName;
                //表的ID
                mTable.TableObjectID = Guid.NewGuid().ToString();
                //表的中文名称
                mTable.Name = sheet.GetRow(iRow).GetCell(iCell + 2).ToString().Trim();
                //表的英文名称
                mTable.Code = sheet.GetRow(iRow + 1).GetCell(iCell + 2).ToString().Trim();
                //表的描述
                mTable.Comment = mTable.Name;

                //标题列 2014-05-03杜冬军修改,动态读取列,确保列顺序
                var row = sheet.GetRow(iRow+3);
                //缓存列索引和名称
                Dictionary<int, string> dic = new Dictionary<int, string>();
                for (int i = iCell; i < row.LastCellNum; i++)
                {
                    dic.Add(i, row.GetCell(i).ToString().Trim());
                }

                iRow = iRow + 4;
                row = sheet.GetRow(iRow);
                while (row != null)
                {
                    if (row.GetCell(iCell) != null && !String.IsNullOrEmpty(row.GetCell(iCell).ToString()))
                    {
                        InitColumns(row, iCell, mTable,dic);
                        iRow = iRow + 1;
                        row = sheet.GetRow(iRow);
                    }
                    else
                    {
                        break;
                    }

                }

                if (string.IsNullOrEmpty(mTable.Comment))
                {
                    mTable.Comment = mTable.Name;
                }
                if (mTable.ListPkKeyInfo != null && mTable.ListPkKeyInfo.Count > 0)
                {
                    foreach (PkKeyInfo pkInfo in mTable.ListPkKeyInfo)
                    {
                        mTable.PkKeyNameList = mTable.PkKeyNameList + pkInfo.Name + ",";
                    }
                }
                if (!string.IsNullOrEmpty(mTable.PkKeyNameList))
                {
                    mTable.PkKeyNameList = mTable.PkKeyNameList.Substring(0, mTable.PkKeyNameList.Length - 1);
                }
                Tables.Add(mTable);
                return iRow;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// 获取表中的列信息
        /// </summary>
        /// <param name="row">列节点</param>
        /// <param name="iCell">列起始索引</param>
        /// <param name="pTable">表信息</param>
        /// <param name="dic">列名字典集合</param>
        private void InitColumns(IRow row, int iCell, TableInfo pTable, Dictionary<int, string> dic)
        {
            ColumnInfo mColumn = new ColumnInfo();
            //列ID
            mColumn.ColumnObjectId = Guid.NewGuid().ToString();
            string sTemp = "";
            int LastCellIndex = dic.Keys.Last<int>();
            for (int i = dic.Keys.First<int>(); i <= LastCellIndex; i++)
            {
                //2014-07-01杜冬军修改,row.LastCellNum取出来有误,确保不出现空异常
                sTemp = row.GetCell(i) == null ? "" : row.GetCell(i).ToString().Trim();
                Common.GetColumnInfo(dic, sTemp, mColumn, i, pTable);
            }
            mColumn.DataTypeStr = Common.GetDataTypeStr(mColumn.DataTypeStr, mColumn.Width);
            mColumn.Width = Common.GetColumnWidth(mColumn.DataTypeStr);

            if (string.IsNullOrEmpty(mColumn.Comment))
            {
                mColumn.Comment = mColumn.Name;
            }
            if (string.IsNullOrEmpty(mColumn.DefaultValue))
            {
                mColumn.DefaultValue = "";
            }
            mColumn.Sequence = pTable.ListColumnInfo.Count + 1;
            pTable.ListColumnInfo.Add(mColumn);
        }
    }
}

上述代码的实现逻辑

  使用NPOI操作EXECL还是很方便的,2.0发布以后支持xlxs文件了,功能更加强大,其实EXECL和WORD的文件结构都是xml文件,只不过是相当复杂的。

NPOI帮我们封装好了这些差异方便使用。工具读取WORD文件之前也是采用NPOI组件,但是性能上存在问题,并且WORD单元格的合并很不好操作,最终采用了

DocX组件来替换它,性能真的提升很多,希望NPOI后面的版本能更好的支持WORD吧。这篇到这里就结束了,敬请期待下一篇DocX操作WORD。

  文中的实例提供下载:NPOIDemo

回到顶部

工具源代码下载

目前总共有经过了七个版本的升级,现在提供最新版本的下载地址

数据字典生成工具V2.0安装程序 最新安装程序
数据字典生成工具源代码 最新源代码

回到顶部

学习使用

如果你使用了该工具,或者想学习该工具,欢迎加入这个小组,一起讨论数据字典生成工具、把该工具做的更强,更方便使用,一起加入147425783 QQ群

      更多数据字典生成工具资料请点击数据字典生成工具专题

数据字典生成工具之旅(4):NPOI操作EXECL,布布扣,bubuko.com

时间: 2024-10-04 02:19:00

数据字典生成工具之旅(4):NPOI操作EXECL的相关文章

数据字典生成工具之旅(5):DocX组件读取与写入Word

由于上周工作比较繁忙,所以这篇文章等了这么久才写(预告一下,下一个章节正式进入NVelocity篇,到时会讲解怎么使用NVelocity做一款简易的代码生成器,敬请期待!),好了正式进入本篇内容. 这篇会介绍DocX读写WORD,DocX组件功能强大,可以很容易的读写WORD,相对于NPOI强大很多,性能也好很多,做这个工具之所以会选择这个组件,主要是看重该组件的表格合并功能. 阅读目录 使用模版生成简历 读写表格数据 合并单元格 工具源代码下载 学习使用 回到顶部 使用模版生成简历 下面将以一

数据字典生成工具之旅(2):数据字典生成工具及文档工具作用介绍

上一篇介绍完了整个架构和功能,这一篇将更加详细介绍功能和操作,将会以实际例子帮助理解!(预告:下一篇正式进入实现原理讲解) 阅读目录 开始使用工具 工具全景图 工具源代码下载 学习使用 回到顶部 开始使用工具 日常工作你是通过什么工具来创建表的呢? 1.通过SqlServer自带的新建表的功能实现,或者直接写Create Table(.....)语句.能更加便捷的方式创建吗?这样创建的表便于后续维护和学习吗? 2.通过PowerDesign创建表,很直观,然后导出表的创建语句.模拟一下做学生信息

数据字典生成工具之旅(6):NVelocity语法介绍及实例

本章开始将会为大家讲解NVelocity的用法,并带领大家实现一个简单的代码生成器. NVelocity是一个基于.NET的模板引擎(template engine).它允许任何人仅仅简单的使用模板语言(template language)来引用由.NET代码定义的对象.从而使得界面设计人员与.NET程序开发人员基本分离. 阅读目录 NVelocity的常用功能简介 基本语法 实例介绍 工具源代码下载 学习使用 回到顶部 NVelocity的常用功能简介 1. 在页面中定义变量,并进行简单的运算

数据字典生成工具之旅(9):多线程使用及介绍

这一篇将在之前的代码生成器上讲解多线程的应用,多线程的概念和好处这里就不多说了,另外从本篇开始后面的实例代码都将放到淘宝的SVN管理工具上维护,大家可以直接使用SVN工具进行下载.好了下面进入本篇内容. 阅读目录 线程的应用 winform程序中的多线程 本章总结 工具源代码下载 学习使用 回到顶部 线程的应用 这里先讲一下线程在Web程序中的一个应用,之前的那一版代码生成器没有考虑表数量多的情形,这里先模拟一下在数据库中创建300张表的情形,下面给出创建表的语句 . --模拟创建300张表,@

数据字典生成工具之旅(8):SQL查询表的约束默认值等信息

上一篇代码生成工具里面已经用到了读取表结构的SQL,这篇将更加详细的介绍SQL SERVER常用的几张系统表和视图! 阅读目录 系统表视图介绍 实际应用 本章总结 工具源代码下载 学习使用 回到顶部 系统表视图介绍 1.sys.tables(用户表) SELECT name,object_id FROM sys.tables 上面SQL是用来查询数据库里面所有用户创建的表,name为表名,object_id为表的对象id.其中object_id的值也可以用系统函数OBJECT_ID()来取 SE

数据字典生成工具(生成Excel, Word,PDF,html)

转自:http://www.cnblogs.com/yanweidie/p/3838765.html 数据字典生成工具之旅系列文章导航 数据字典生成工具之旅系列文章导航 宣传语 数据字典生成工具.数据字典文档生成工具.NPOI入门.NPOI下载.NPOI中文教程.NPOI实例.DocX组件操作Word.PowerDesign读取.WORD读取和操作.NVelocity模版文件生成.数据字典生成工具之旅 导游 数据字典生成工具会根据模版文件生成创建表的SQL语句,包含SQL自动提示功能,操作更加快

数据字典生成工具

之前找的数据库字典生成工具基本上都依赖于 Office Com 组件,在不安装 Office的情况下无法使用.怒,于是自己用C# 写了一个. 特征如下: 一.支持的数据库 MS SQL Server 2005+.My Sql.Oracle 二.支持的文档类型 HTML.CHM. WORD 三.无需安装办公软件即可生成 WORD 格式的文件 四.基于 .net framework 3.5 框架,电脑上需要安装 .net framework 3.5. PS:欢迎反馈BUG ,反馈方式 戳 About

【C#附源码】数据库文档生成工具支持(Excel+Html)

[2015] 很多时候,我们在生成数据库文档时,使用某些工具,可效果总不理想,不是内容不详细,就是表现效果一般般.很多还是word.html的.看着真是别扭.本人习惯用Excel,所以闲暇时,就简单的编写了数据库文档生成工具,供大家交流学习之用,与程序员共勉.     该工具为C#控制台,以NPOI为基础,操作Excel.简单方便,简单配置.两次回车,OK!即可生成清晰的数据库文档.另外,支持生成HTML文档.源码大小7MB,OS上传不了,放到百度云盘里了:http://pan.baidu.co

DBImport v3.3 中文版发布:数据库数据互导及文档生成工具(IT人员必备)

前言: 好久没写文了, 距离上一篇文章是3个月前的事了,虽然工作很忙,主要还是缺少写作的内容和激情,所以没怎么动手. 之前有一个来月不断面试不同层次来应聘的人员,很有想写文的冲动,后来还是忍住了. 估计写了也是那种说人坏话.恨铁不成钢的情绪文,没啥营养,所以情绪过了就没想写了. 在公司除了管理上的事情之外,另外也研发了一套适用信息系统的快速开发框架,这个有机会再写写文和大伙分享了. 下面言归正文了. 背景: 关于这个DBImport工具,发布的版本不多,仅有:V1.0.V2.0.V3.0.V3.