C#使用NPOI操作Office

什么是NPOI

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

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

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

VisualStudio2019引入NPOI

在Nuget中引入NPOI包
在这里插入图片描述

NPOI操作word

1、word写入

由于NPOI在生成一个word文档时,标识标题等级的字符串是不固定的,这个时候通过使用模板的形式,来使word样式相对固定,也就是使用模板的样式来生成一个word文档,下面看代码:

		XWPFDocument doc;	
		/// <summary>
        /// 根据模板设置word文档样式
        /// </summary>
        public void SetDocStyles()
        {
            using (var dotStream = new FileStream("Resources\\模板.dotx", FileMode.Open, FileAccess.Read))
            {
                dotStream.Position = 0;
                XWPFDocument template = new XWPFDocument(dotStream);
                doc = new XWPFDocument();
                XWPFStyles newStyles = doc.CreateStyles();
                newStyles.SetStyles(template.GetCTStyle());
            }
        }
		
        /// <summary>
        /// 创建一个段落(也可以是标题)
        /// </summary>
        /// <param name="content">文字内容</param>
        /// <param name="styleId">样式id,代表是多级标题或者段落正文</param>
        /// <param name="fontFamily">字体</param>
        /// <param name="IsBold">是否加粗</param>
        /// <param name="fontSize">文字大小</param>
        /// <param name="color">文字颜色</param>
        /// <param name="paragraphAlignment">水平位置</param>
        public void Write(string content, int fontSize, string styleId, string fontFamily, bool IsBold = false, string color = "black", ParagraphAlignmentCustom paragraphAlignment = ParagraphAlignmentCustom.Left)
        {
            XWPFParagraph ptitle = doc.CreateParagraph();
            if(paragraphAlignment == ParagraphAlignmentCustom.Left)
                ptitle.Alignment = ParagraphAlignment.LEFT;
            else if (paragraphAlignment == ParagraphAlignmentCustom.Center)
                ptitle.Alignment = ParagraphAlignment.CENTER;
            XWPFRun titlerun = ptitle.CreateRun();
            titlerun.SetText(content);
            titlerun.IsBold = IsBold;
            titlerun.FontFamily = fontFamily;
            titlerun.FontSize = fontSize;
            titlerun.SetColor(color);
            ptitle.Style = styleId;
            ptitle.SetNumID("");
        }

        /// <summary>
        /// 插入图片
        /// </summary>
        /// <param name="picPath"></param>
        /// <param name="pictureName"></param>
        public void InsertPicture(string picPath,string pictureName)
        {
            FileStream gfs = new FileStream(picPath, FileMode.Open, FileAccess.Read);
            CT_P m_p = doc.Document.body.AddNewP();
            m_p.AddNewPPr().AddNewJc().val = ST_Jc.center;//段落水平居中
            XWPFParagraph gp = new XWPFParagraph(m_p, doc);//创建段落
            XWPFRun gr = gp.CreateRun();//创建run
            //在run中插入图片
            gr.AddPicture(gfs, (int)PictureType.PNG, pictureName, 5300000, 2500000);
        }

        /// <summary>
        /// 保存word文档
        /// </summary>
        /// <param name="filePath"></param>
        public void SaveDoc(string filePath)
        {
            FileStream fs = new FileStream(filePath, FileMode.Create);
            doc.Write(fs);
            fs.Close();
            doc.Close();
        }

2、word读取

        /// <summary>
        /// 获取word文档所有段落
        /// </summary>
        /// <param name="filePath"></param>
        /// <returns></returns>
        private List<XWPFParagraph> GetParagraphs(string filePath)
        { 
       		var dotStream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
            XWPFDocument doc = new XWPFDocument(dotStream);
            foreach(var paragraph in doc.Paragraphs)
            {
            	var styleId=paragraph.StyleID;//标题等级标识
            }
            return doc.Paragraphs;
        }

NPOI操作Excel

这是一个大佬写的,用到的很全面,传送门:https://www.cnblogs.com/knowledgesea/archive/2012/11/16/2772547.html

		//创建一个常用的xls文件
        private void button3_Click(object sender, EventArgs e)
        {          
            IWorkbook wb = new HSSFWorkbook();
            //创建表  
            ISheet sh = wb.CreateSheet("zhiyuan");
            //设置单元的宽度  
            sh.SetColumnWidth(0, 15 * 256);
            sh.SetColumnWidth(1, 35 * 256);
            sh.SetColumnWidth(2, 15 * 256);
            sh.SetColumnWidth(3, 10 * 256);
            int i = 0;
            #region 练习合并单元格            sh.AddMergedRegion(new NPOI.SS.Util.CellRangeAddress(0, 0, 0, 3));
            //CellRangeAddress()该方法的参数次序是:开始行号,结束行号,开始列号,结束列号。              IRow row0 = sh.CreateRow(0);
            row0.Height = 20 * 20;
            ICell icell1top0 = row0.CreateCell(0);
            icell1top0.CellStyle = Getcellstyle(wb, stylexls.);
            icell1top0.SetCellValue("标题合并单元");
            #endregion
            i++;
            #region 设置表头
            IRow row1 = sh.CreateRow(1);
            row1.Height = 20 * 20;

            ICell icell1top = row1.CreateCell(0);
            icell1top.CellStyle = Getcellstyle(wb, stylexls.);
            icell1top.SetCellValue("网站名");

            ICell icell2top = row1.CreateCell(1);
            icell2top.CellStyle = Getcellstyle(wb, stylexls.);
            icell2top.SetCellValue("网址");

            ICell icell3top = row1.CreateCell(2);
            icell3top.CellStyle = Getcellstyle(wb, stylexls.);
            icell3top.SetCellValue("百度快照");

            ICell icell4top = row1.CreateCell(3);
            icell4top.CellStyle = Getcellstyle(wb, stylexls.);
            icell4top.SetCellValue("百度收录");
            #endregion  
  
            using(FileStream stm=File.OpenWrite(@"c:/myMergeCell.xls"))
            {
                wb.Write(stm); 
                MessageBox.Show("提示:创建成功!");
            }
        }



        #region 定义单元格常用到样式的枚举
        public enum stylexls
        {,
            url,
            时间,
            数字,,
            百分比,
            中文大写,
            科学计数法,
            默认
        }
        #endregion


        #region 定义单元格常用到样式
        static ICellStyle Getcellstyle(IWorkbook wb, stylexls str)
        {
            ICellStyle cellStyle = wb.CreateCellStyle();

            //定义几种字体  
            //也可以一种字体,写一些公共属性,然后在下面需要时加特殊的  
            IFont font12 = wb.CreateFont();
            font12.FontHeightInPoints = 10;
            font12.FontName = "微软雅黑";


            IFont font = wb.CreateFont();
            font.FontName = "微软雅黑";
            //font.Underline = 1;下划线  


            IFont fontcolorblue = wb.CreateFont();
            fontcolorblue.Color = HSSFColor.OLIVE_GREEN.BLUE.index;
            fontcolorblue.IsItalic = true;//下划线  
            fontcolorblue.FontName = "微软雅黑";


            //边框  
            cellStyle.BorderBottom = NPOI.SS.UserModel.BorderStyle.DOTTED;
            cellStyle.BorderLeft = NPOI.SS.UserModel.BorderStyle.HAIR;
            cellStyle.BorderRight = NPOI.SS.UserModel.BorderStyle.HAIR;
            cellStyle.BorderTop = NPOI.SS.UserModel.BorderStyle.DOTTED;
            //边框颜色  
            cellStyle.BottomBorderColor = HSSFColor.OLIVE_GREEN.BLUE.index;
            cellStyle.TopBorderColor = HSSFColor.OLIVE_GREEN.BLUE.index;

            //背景图形,我没有用到过。感觉很丑  
            //cellStyle.FillBackgroundColor = HSSFColor.OLIVE_GREEN.BLUE.index;  
            //cellStyle.FillForegroundColor = HSSFColor.OLIVE_GREEN.BLUE.index;  
            cellStyle.FillForegroundColor = HSSFColor.WHITE.index;
            // cellStyle.FillPattern = FillPatternType.NO_FILL;  
            cellStyle.FillBackgroundColor = HSSFColor.BLUE.index;

            //水平对齐  
            cellStyle.Alignment = NPOI.SS.UserModel.HorizontalAlignment.LEFT;

            //垂直对齐  
            cellStyle.VerticalAlignment = VerticalAlignment.CENTER;

            //自动换行  
            cellStyle.WrapText = true;

            //缩进;当设置为1时,前面留的空白太大了。希旺官网改进。或者是我设置的不对  
            cellStyle.Indention = 0;

            //上面基本都是设共公的设置  
            //下面列出了常用的字段类型  
            switch (str)
            {
                case stylexls.:
                    // cellStyle.FillPattern = FillPatternType.LEAST_DOTS;  
                    cellStyle.SetFont(font12);
                    break;
                case stylexls.时间:
                    IDataFormat datastyle = wb.CreateDataFormat();

                    cellStyle.DataFormat = datastyle.GetFormat("yyyy/mm/dd");
                    cellStyle.SetFont(font);
                    break;
                case stylexls.数字:
                    cellStyle.DataFormat = HSSFDataFormat.GetBuiltinFormat("0.00");
                    cellStyle.SetFont(font);
                    break;
                case stylexls.:
                    IDataFormat format = wb.CreateDataFormat();
                    cellStyle.DataFormat = format.GetFormat("¥#,##0");
                    cellStyle.SetFont(font);
                    break;
                case stylexls.url:
                    fontcolorblue.Underline = 1;
                    cellStyle.SetFont(fontcolorblue);
                    break;
                case stylexls.百分比:
                    cellStyle.DataFormat = HSSFDataFormat.GetBuiltinFormat("0.00%");
                    cellStyle.SetFont(font);
                    break;
                case stylexls.中文大写:
                    IDataFormat format1 = wb.CreateDataFormat();
                    cellStyle.DataFormat = format1.GetFormat("[DbNum2][$-804]0");
                    cellStyle.SetFont(font);
                    break;
                case stylexls.科学计数法:
                    cellStyle.DataFormat = HSSFDataFormat.GetBuiltinFormat("0.00E+00");
                    cellStyle.SetFont(font);
                    break;
                case stylexls.默认:
                    cellStyle.SetFont(font);
                    break;
            }
            return cellStyle;


        }
        #endregion

使用NPOI遇到的坑

1、NPOI操作word的时候,在上面方法中Write的参数“styleId”是一个坑,因为styleid根据不同文档值不同,比如在A文档中的标题1对应的styleId为“a5”,但是在B文档中的标题1对应的可能是“17”。所以我使用了一个word模板,可以通过调试拿到模板中各个段落的styleId,在生成word时会用到。
2、在操作word时,write方法中开始没有写最后一句“ptitle.SetNumID("");”,在生成word文档之后,wps打开正常,用msword打开后则自动产生了标题编号,但是调试的时候ptitle.NumLevelText的值却是null,最后尝试ptitle.SetNumID(""),再次用msword打开,显示正常了。

如果有不对的地方,还请指出,共同进步!

  • 5
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值