使用NPOI编辑Office(Excel)
声明:我是用Unity写的,以下代码在5.5.2中运行通过,unity都能过了,所以C#肯定没问题的…………..NPOI的dll在网上找找吧。。。
NPOI简介
http://blog.csdn.net/pan_junbiao/article/details/39717443
1.1 什么是NPOINPOI,顾名思义,就是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.html1.3 相关资源官方网站:http://npoi.codeplex.com/POIFS Browser 1.2下载地址:http://npoi.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=243051.4 团队介绍Tony Qu来自于中国上海,是这个项目的发起人和开发人员,时区是GMT+8,2008年9月开始了NPOI的开发,负责NPOI所有底层库的开发、测试和bug修复。个人blog地址为http://tonyqus.cnblogs.com/HüseyinTüfekçilerli来自于土耳其的伊斯坦布尔,也是这个项目的开发人员,时区是GMT+2,2008年11月参与了NPOI的开发,主要负责POIFS Browser 1.0的开发工作。个人blog地址为http://huseyint.com/aTao.Xiang,来自中国,2009年8月开始参与该项目,主要参与了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 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");//执行创建好的文件}
插入图片
插这个图片真是累得要死,二张图片以上的时候还会覆盖 ,找了好久资料才找到,太多了。。。即便如此,这些参数也是试了好多次才知道是什么意思。。。很抱歉,实在记不清楚看得哪个大神写的帖子了
/// /// 向excel添加一个图片/// /// excel/// sheet/// 图片的名字,没有后缀/// excel中图片的左上角的单元格行/// excel中图片的右上角的单元格行/// excel中图片的左下角的单元格列/// excel中图片的右下角的单元格列public static void AddPicture(HSSFWorkbook workbook, HSSFSheet sheet1, string pngPath, int x1, int y1, int x2, int y2){//将图片加入Workbookbyte[] 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;/// /// 向excel添加一个图片/// /// excel/// sheet/// 图片的名字,没有后缀/// excel中图片的左上角的单元格行/// excel中图片的右上角的单元格行/// excel中图片的左下角的单元格列/// excel中图片的右下角的单元格列public static void AddPicture(HSSFWorkbook workbook, HSSFSheet sheet1, string pngPath, int x1, int y1, int x2, int y2){//将图片加入Workbookbyte[] 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 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
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
