使用NPOI编辑Office(Excel)

声明:我是用Unity写的,以下代码在5.5.2中运行通过,unity都能过了,所以C#肯定没问题的…………..NPOI的dll在网上找找吧。。。

NPOI简介

http://blog.csdn.net/pan_junbiao/article/details/39717443

1.1 什么是NPOI

NPOI,顾名思义,就是POI的.NET版本。那POI又是什么呢?POI是一套用Java写成的库,能够帮助开发者在没有安装微软Office的情况下读写Office 97-2003的文件,支持的文件格式包括xls, doc, ppt等。在本文发布时,POI的最新版本是3.5 beta 6。

NPOI 1.x是基于POI 3.x版本开发的,与poi 3.2对应的版本是NPOI 1.2,目前最新发布的版本是1.2.1,在该版本中仅支持读写Excel文件和Drawing格式,其他文件格式将在以后的版本中得到支持。



1.2 版权说明

NPOI采用的是Apache 2.0许可证(poi也是采用这个许可证),这意味着它可以被用于任何商业或非商业项目,你不用担心因为使用它而必须开放你自己的源代码,所以它对于很多从事业务系统开发的公司来说绝对是很不错的选择。

当然作为一个开源许可证,肯定也是有一些义务的,例如如果你在系统中使用NPOI,你必须保留NPOI中的所有声明信息。对于源代码的任何修改,必须做出明确的标识。

完整的apache 2.0许可证请见http://www.phpx.com/man/Apache-2/license.html



1.3 相关资源

官方网站:http://npoi.codeplex.com/

POIFS Browser 1.2

下载地址:http://npoi.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=24305


1.4 团队介绍

Tony Qu来自于中国上海,是这个项目的发起人和开发人员,时区是GMT+820089月开始了NPOI的开发,负责NPOI所有底层库的开发、测试和bug修复。

个人blog地址为http://tonyqus.cnblogs.com/


HüseyinTüfekçilerli来自于土耳其的伊斯坦布尔,也是这个项目的开发人员,时区是GMT+2200811月参与了NPOI的开发,主要负责POIFS Browser 1.0的开发工作。

个人blog地址为http://huseyint.com/



aTao.Xiang,来自中国,20098月开始参与该项目,主要参与了NPOI 1.2中文版的撰写工作和推广工作

个人blog地址为http://www.cnblogs.com/atao/



1.5 回顾与展望

目前POI版本中的HWPF(用于Word的读写库)还不是很稳定,并非正式发布版本,且负责HWPF的关键开发人员已经离开,所以NPOI可能考虑自己重新开发HWPF。另外,目前微软正在开发Open XML Format SDK,NPOI可能会放弃对ooxml的支持,当然这取决于用户的需求和Open XML Format SDK的稳定性和速度。从目前而言,NPOI有几大优势

第一,完全基于.NET 2.0,而非.NET 3.0/3.5。

第二,读写速度快(有个国外的兄弟回复说,他原来用ExcelPackage生成用了4-5个小时,现在只需要4-5分钟)

第三,稳定性好(相对于用Office OIA而言,毕竟那东西是基于Automation做的,在Server上跑个Automation的东西,想想都觉得可怕),跑过了将近1000个测试用例(来自于POI的testcase目录)

第四,API简单易用,当然这得感谢POI的设计师们

第五,完美支持Excel 2003格式(据说myxls无法正确读取xls模板,但NPOI可以),以后也许是所有Office 2003格式

希望NPOI把这些优势继续发扬下去,这样NPOI才会更有竞争力。



1.6 NPOI 1.2中各Assembly的作用

NPOI目前有好几个assembly,每个的作用各有不同,开发人员可以按需加载相应的assembly。在这里大概罗列一下:

NPOI.Util  基础辅助库
NPOI.POIFS   OLE2格式读写库
NPOI.DDF   Microsoft Drawing格式读写库
NPOI.SS   Excel公式计算库
NPOI.HPSF   OLE2的Summary Information和Document Summary Information属性读写库
NPOI.HSSF   Excel BIFF格式读写库

使用NPOI写Excel——插入数据

 public static void WriteExcel(List<MyRebar> list)
    {
        HSSFWorkbook workbook2003 = new HSSFWorkbook(); //新建工作簿  
        workbook2003.CreateSheet("Sheet1");  //新建1个Sheet工作表              
        HSSFSheet SheetOne = (HSSFSheet)workbook2003.GetSheet("Sheet1"); //获取名称为Sheet1的工作表  

        HSSFCell[] SheetCell;//单元格//先申明一些变量
        CellRangeAddress range;//合并
        IRow row;       //行

        //对工作表先添加行,下标从0开始  
        for (int k = 0; k < list.Count; k++)
        {
            row = SheetOne.CreateRow(k);   //创建10行  
            row.HeightInPoints = 40;//设置单元格的高度
            row = (HSSFRow)SheetOne.GetRow(k);  //获取Sheet1工作表的首行  
            SheetCell = new HSSFCell[10];     //对每一行创建10个单元格  

            for (int i = 0; i < 10; i++)
            {
                SheetCell[i] = (HSSFCell)row.CreateCell(i);  //为第一行创建10个单元格  
            }
            SheetCell[0].SetCellValue(list[k].SerialNumber);//创建之后就可以赋值了  
            SheetCell[1].SetCellValue(list[k].CardNum);
            SheetCell[2].SetCellValue(list[k].Name);
            SheetCell[6].SetCellValue(list[k].Length);
            SheetCell[7].SetCellValue(list[k].Quantity);
            SheetCell[8].SetCellValue(list[k].Weight);
            SheetCell[9].SetCellValue(list[k].Reamarks);

            HSSFCellStyle fCellStyle = (HSSFCellStyle)workbook2003.CreateCellStyle();//创建单元格的一些格式
            HSSFFont ffont = (HSSFFont)workbook2003.CreateFont();
            ffont.FontHeight = 15 * 15;//字体的高度及宽度
            ffont.FontName = "宋体";//字体
            ffont.IsBold = true;//是否加粗
            fCellStyle.FillBackgroundColor = HSSFColor.Red.Index;//改变背景颜色?没有效果,使用另一个插件时候是可以的
            fCellStyle.SetFont(ffont);
            SheetCell[0].CellStyle = fCellStyle;//给这个单元格添加刚刚写好的格式

            range = new CellRangeAddress(k, k, 3, 5);//想要合并的范围(参数分别是单元格的左上角坐标(行X,列Y),右下角的坐标(行X,列Y))
            SheetOne.AddMergedRegion(range);

            SheetCell[0].CellStyle.Alignment = HorizontalAlignment.Center;//对齐方式,只能有一种?二种以上会覆盖之前的
            SheetCell[0].CellStyle.VerticalAlignment = VerticalAlignment.Center;
        }
        index = PlayerPrefs.GetInt("KEY");//测试
        index++;
        PlayerPrefs.SetInt("KEY", index);
        FileStream file2003 = new FileStream(@"E:\Excel2003" + index + ".xls", FileMode.Create);//创建一个文件
        workbook2003.Write(file2003);
        file2003.Close();
        workbook2003.Close();//保存
        Application.OpenURL(@"E:\Excel2003" + index + ".xls");//执行创建好的文件
    }

插入图片

插这个图片真是累得要死,二张图片以上的时候还会覆盖 ,找了好久资料才找到,太多了。。。即便如此,这些参数也是试了好多次才知道是什么意思。。。很抱歉,实在记不清楚看得哪个大神写的帖子了

 /// <summary>
    /// 向excel添加一个图片
    /// </summary>
    /// <param name="workbook">excel</param>
    /// <param name="sheet1">sheet</param>
    /// <param name="pngPath">图片的名字,没有后缀</param>
    /// <param name="x1">excel中图片的左上角的单元格行</param>
    /// <param name="y1">excel中图片的右上角的单元格行</param>
    /// <param name="x2">excel中图片的左下角的单元格列</param>
    /// <param name="y2">excel中图片的右下角的单元格列</param>
    public static void AddPicture(HSSFWorkbook workbook, HSSFSheet sheet1, string pngPath, int x1, int y1, int x2, int y2)
    {
        //将图片加入Workbook
        byte[] bytes = File.ReadAllBytes(@"D:\Work001\Work001\Assets\Resources\Sprites2\" + pngPath + ".png");//读取图片转换为流
        int pictureIdx1 = workbook.AddPicture(bytes, PictureType.JPEG);//图片的格式?好像没什么用,换了几种格式都是一样的
        IDrawing patriarch = sheet1.CreateDrawingPatriarch();   //获取存在的Sheet,必须在AddPicture之后

        HSSFClientAnchor anchor;
        anchor = new HSSFClientAnchor(0, 0, 1023, 0, x1, y1, x2, y2);//插入图片
        patriarch.CreatePicture(anchor, pictureIdx1);
    }

完整代码

using System.Collections.Generic;
using NPOI.SS.UserModel;
using NPOI.HSSF.UserModel;
using System.IO;
using UnityEngine;
using NPOI.SS.Util;
using NPOI.HSSF.Util;

public class MakeExcel : MonoBehaviour
{
    public static int index = 0;
    /// <summary>
    /// 向excel添加一个图片
    /// </summary>
    /// <param name="workbook">excel</param>
    /// <param name="sheet1">sheet</param>
    /// <param name="pngPath">图片的名字,没有后缀</param>
    /// <param name="x1">excel中图片的左上角的单元格行</param>
    /// <param name="y1">excel中图片的右上角的单元格行</param>
    /// <param name="x2">excel中图片的左下角的单元格列</param>
    /// <param name="y2">excel中图片的右下角的单元格列</param>
    public static void AddPicture(HSSFWorkbook workbook, HSSFSheet sheet1, string pngPath, int x1, int y1, int x2, int y2)
    {
        //将图片加入Workbook
        byte[] bytes = File.ReadAllBytes(@"D:\Work001\Work001\Assets\Resources\Sprites2\" + pngPath + ".png");//读取图片转换为流
        int pictureIdx1 = workbook.AddPicture(bytes, PictureType.JPEG);//图片的格式?好像没什么用,换了几种格式都是一样的
        IDrawing patriarch = sheet1.CreateDrawingPatriarch();   //获取存在的Sheet,必须在AddPicture之后

        HSSFClientAnchor anchor;
        anchor = new HSSFClientAnchor(0, 0, 1023, 0, x1, y1, x2, y2);//插入图片
        patriarch.CreatePicture(anchor, pictureIdx1);
    }

    public static void WriteExcel(List<MyRebar> list)
    {
        HSSFWorkbook workbook2003 = new HSSFWorkbook(); //新建工作簿  
        workbook2003.CreateSheet("Sheet1");  //新建1个Sheet工作表              
        HSSFSheet SheetOne = (HSSFSheet)workbook2003.GetSheet("Sheet1"); //获取名称为Sheet1的工作表  

        HSSFCell[] SheetCell;//单元格//先申明一些变量
        CellRangeAddress range;//合并
        IRow row;       //行

        //对工作表先添加行,下标从0开始  
        for (int k = 0; k < list.Count; k++)
        {
            row = SheetOne.CreateRow(k);   //创建10行  
            row.HeightInPoints = 40;//设置单元格的高度
            row = (HSSFRow)SheetOne.GetRow(k);  //获取Sheet1工作表的首行  
            SheetCell = new HSSFCell[10];     //对每一行创建10个单元格  

            for (int i = 0; i < 10; i++)
            {
                SheetCell[i] = (HSSFCell)row.CreateCell(i);  //为第一行创建10个单元格  
            }
            SheetCell[0].SetCellValue(list[k].SerialNumber);//创建之后就可以赋值了  
            SheetCell[1].SetCellValue(list[k].CardNum);
            SheetCell[2].SetCellValue(list[k].Name);
            SheetCell[6].SetCellValue(list[k].Length);
            SheetCell[7].SetCellValue(list[k].Quantity);
            SheetCell[8].SetCellValue(list[k].Weight);
            SheetCell[9].SetCellValue(list[k].Reamarks);

            HSSFCellStyle fCellStyle = (HSSFCellStyle)workbook2003.CreateCellStyle();//创建单元格的一些格式
            HSSFFont ffont = (HSSFFont)workbook2003.CreateFont();
            ffont.FontHeight = 15 * 15;//字体的高度及宽度
            ffont.FontName = "宋体";//字体
            ffont.IsBold = true;//是否加粗
            fCellStyle.FillBackgroundColor = HSSFColor.Red.Index;//改变背景颜色?没有效果,使用另一个插件时候是可以的
            fCellStyle.SetFont(ffont);
            SheetCell[0].CellStyle = fCellStyle;//给这个单元格添加刚刚写好的格式

            range = new CellRangeAddress(k, k, 3, 5);//想要合并的范围(参数分别是单元格的左上角坐标(行X,列Y),右下角的坐标(行X,列Y))
            SheetOne.AddMergedRegion(range);

            SheetCell[0].CellStyle.Alignment = HorizontalAlignment.Center;//对齐方式,只能有一种?二种以上会覆盖之前的
            SheetCell[0].CellStyle.VerticalAlignment = VerticalAlignment.Center;
        }
        index = PlayerPrefs.GetInt("KEY");//测试
        index++;
        PlayerPrefs.SetInt("KEY", index);
        FileStream file2003 = new FileStream(@"E:\Excel2003" + index + ".xls", FileMode.Create);//创建一个文件
        workbook2003.Write(file2003);
        file2003.Close();
        workbook2003.Close();//保存
        Application.OpenURL(@"E:\Excel2003" + index + ".xls");//执行创建好的文件
    }
}

———————————-

精确设置列宽

* 参数只支持int所以还不是特别精确,,,NPOI生成Excel文件时,设置列宽只有一函数sheet.SetColumnWidth(),该函数有两个参数,第一个是行索引,第二个是行列宽。但是在实际使用过程中,设置的行列宽与产生的Excel文件行列宽不一致。经过实际测试,只需要加一个常量即可:*

sheet.SetColumnWidth(0, 16 * 256 + 200); // 200为常量,这样即可控制列宽为16  

原文:

http://blog.csdn.net/echoshinian100/article/details/46764487

设置对齐方式

     HSSFCellStyle fCellStyle;
        HSSFFont ffont;

        fCellStyle = (HSSFCellStyle)workbook2003.CreateCellStyle();
        ffont = (HSSFFont)workbook2003.CreateFont();
        ffont.FontHeight = 15 * 15;
        ffont.FontName = "宋体";
        ffont.Color = HSSFColor.Red.Index;
        ffont.IsBold = fontIsBold;
        fCellStyle.FillForegroundColor = 40;
        fCellStyle.SetFont(ffont);
        fCellStyle.Alignment = hori;
        fCellStyle.VerticalAlignment = VerticalAlignment.Center;
        SheetCell[index].CellStyle = fCellStyle;

边框线设置

        fCellStyle.BorderBottom = BorderStyle.Thin;
        fCellStyle.BorderLeft = BorderStyle.Thin;
        fCellStyle.BorderRight = BorderStyle.Thin;
        fCellStyle.BorderTop = BorderStyle.Thin;

参考:

http://bbs.csdn.net/topics/390960435?locationNum=8&fps=1

样式的枚举

注意

样式的数量是有限的,多了会超出限制,没必要每一个单元格都去createstyle 可以在循环外面 创建几种需要的样式出来 用的时候直接 cellstyle=你创建好的样式,样式创建的不要太多,使用一个变量循环赋值就可以了,否则会报空?忘记截图了

读取Excel并写入数据

上边都是直接创建的一个表,上边都写过读取也就没什么难度了

using System.Collections.Generic;
using NPOI.SS.UserModel;
using NPOI.HSSF.UserModel;
using System.IO;
using UnityEngine;
public class MakeExcel
{
    public static void WriteExcel(string filePath)
    {
        IWorkbook book = null; //置空  
        FileStream fs = File.OpenRead(filePath);//打开表
        book = new HSSFWorkbook(fs);//读取表
        fs.Close();
        ISheet sheet = book.GetSheetAt(0); //获取名称为第0个工作表  
        IRow row = sheet.GetRow(0);  //读取当前行数据
        for (int i = 0; i <= sheet.LastRowNum; i++)        //LastRowNum 是当前表的总行数-1(注意)
        {
            row = sheet.GetRow(i);  //读取当前行数据
            if (row != null)
            {
                string s = "";
                for (int j = 0; j < row.LastCellNum; j++)//LastCellNum 是当前行的总列数
                {
                    //读取该行的第j列数据
                    string value = row.GetCell(j).ToString();
                    s += value;//对每一行的列的数据累加,得到一行的数据
                }
                Debug.Log(s);//一行的数据
            }
        }
    }
}

http://www.bianceng.cn/Programming/csharp/201410/45750.htm

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值