C#使用NPOI对word进行读写

目录

  • 一、简介
    • 操作Word的类库:
  • 二、简单使用
    • 1、XWPFDocument类的实例化
    • 2、设置页面的大小
    • 3、段落处理
    • 4、表格处理
    • 5、页眉页脚处理
  • 三、综合示例
    • 四、参考

      一、简介
      操作Word的类库:
      • NPOI: V2.5.1 快速生成 https://github.com/tonyqus/npoi
      • DocX(属于Xceed Words for .NET的免费版本): V1.6.0 https://github.com/xceedsoftware/DocX
      • Aspose.Words: 收费
      • Spire.Doc: 收费

      二、简单使用
      1、XWPFDocument类的实例化
      该类的实例对应一个word文档
      XWPFDocument MyDoc = new XWPFDocument();


      2、设置页面的大小
      如果不进行页面大小的设置,默认是纵向的A4大小。横向的A4的页面大小 ,如果要纵向,宽高两个值调换即可。
      T_SectPr m_SectPr = new CT_SectPr(); //实例一个尺寸类的实例m_SectPr.pgSz.w = 16838; //设置宽度(这里是一个ulong类型)m_SectPr.pgSz.h = 11906; //设置高度(这里是一个ulong类型)MyDoc.Document.body.sectPr = m_SectPr; //设置页面的尺寸

      这里的单位比较特殊,用的是缇(Twip)这是一种和屏幕无关的长度单位,目的是为了让应用程序元素输出到不同设备时都能保持一致的计算方式。
      换算关系:
      • 1英寸=1440缇
      • 1厘米=567缇
      • 1磅=20缇
      • 1像素=15缇
      常用页面尺寸:(单位Twip)
      • A4(纵向):W=11906 H=16838
      • A4(纵向):W=16838 H=11906
      • A5 : W=8390 H=11906
      • A6 : W=5953 H=8390
      示例:控制word页内边距
      //创建document对象var doc = new XWPFDocument(); doc.Document.body.sectPr = new CT_SectPr(); CT_SectPr m_SectPr = doc.Document.body.sectPr; m_SectPr.pgSz.h = (ulong)16838; m_SectPr.pgSz.w = (ulong)11906; //页面边距m_SectPr.pgMar.left = (ulong)800; //左边距m_SectPr.pgMar.right = (ulong)800; //右边距m_SectPr.pgMar.top = "850"; //上边距m_SectPr.pgMar.bottom = "850"; //下边距


      3、段落处理
      创建段落
      段落为XWPFParagraph类型的实例,段落由XWPFDocument实例的使用CreateParagraph()方法生成。
      XWPFParagraph MyParagraph = MyDoc.CreateParagraph();

      该段落类有很多属性,用于设置与段落相关的内容。主要有以下几个方面
      • BorderXXXXX属性:该值用于设置边界的样式。该属性用于获取或设置一个Borders枚举类型的值,
      • FillBackgroundColor属性:背景填充的颜色。该属性获取或设置一个string类型的变量。该变量的含义是某个颜色的RGB值(在NPOI里所有的颜色都是以这种形式表示的)。例如设置为黑色则对应的代码如下:
        MyParagraph.FillBackgroundColor = "#000000";

      • Alignment属性:段落的对齐方式。该属性获取或设置一个ParagraphAlignment的枚举值。
      • VerticalAlignment属性:文本垂直方向的对齐方式。该属性获取或设置一个TextAlignment 的枚举值。
      • IndentationFirstLine属性:用于设置段落的首行缩进。该属性获取或设置一个int型变量。
        这个int值并不是缩进的字数,这里可以用一个函数计算缩进的距离。
      //段落缩进返回值为对应的缩进距离//(fontname:文字类型名称fontsize:文字大小fontcount:缩进数目 fontstyle:文字类型(斜体、粗体...))int Indentation(String fontname, int fontsize, int fontnum, FontStyle fontstyle){Graphics gp = this.CreateGraphics(); gp.PageUnit = GraphicsUnit.Point; SizeF size = gp.MeasureString("字", new Font(fontname, fontsize * 0.75F, fontstyle)); return (int)size.Width * fontnum * 10; }

      示例:创建段落
      var paragraph = doc.CreateParagraph(); paragraph.Alignment = ParagraphAlignment.CENTER; //字体居中var run = paragraph.CreateRun(); run.IsBold = true; run.SetText(contend); run.FontSize = 28; run.SetFontFamily("黑体", FontCharRange.None); //设置黑体//控制段落与其他元素的上下距离paragraph.SpacingBeforeLines = 20; //上方距离paragraph.SpacingAfterLines = 20; //下方距离

      换页(本页未满直接写下一页)
      paragraph = doc.CreateParagraph(); paragraph.CreateRun().AddBreak(BreakType.PAGE);

      文本处理
      • doc.Paragraphs 获取到文档里的所有的段落对象;
      • para.ParagraphText 获取段落的文本数据;
      • para.ReplaceText(要被替换的文本,替换文本) 替换段落的文本(模板能实现的关键)

      4、表格处理
      doc.Tables 获取文档里的所有的表格对象;//doc.Tables获取的只是Word中最外层的表格,不包含嵌套内层的。
      cell.Tables;//获取嵌套单元格可使用
      row.Rows //获取表格所有行;
      row.GetTableICells() ; //获取表格行的所有单元格;
      获取到单元格之后就可以获取单元格里的文本段落(Paragraphs)并且进行文本替换
      创建表格
      var table = doc.CreateTable(行数, 列数); table.Width = 5000;

      【C#使用NPOI对word进行读写】控制表格中列宽(这里需要注意,只设置一行的列宽一旦插入文字就会使设置的列宽失效,所以要把每一个单元格都要设置上)
      for (int r = 0; r < 8; r++){SetCellWith(table.GetRow(r).GetCell(0), "600"); SetCellWith(table.GetRow(r).GetCell(1), "1500"); SetCellWith(table.GetRow(r).GetCell(2), "1500"); SetCellWith(table.GetRow(r).GetCell(3), "600"); }

      设置表格中单元格竖直居中
      var rowcell = table.GetRow(r).GetCell(c); rowcell.SetVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);

      设置单元格内容
      //table中的文字格式设置var para = new CT_P(); var pCell = new XWPFParagraph(para, table.Body); pCell.Alignment = paragraphAlignment; //字体居中pCell.VerticalAlignment = TextAlignment.CENTER; //字体居中var r1c1 = pCell.CreateRun(); r1c1.SetText(setText); r1c1.FontSize = 11; r1c1.SetFontFamily("宋体", FontCharRange.None); //设置雅黑字体pCell.SpacingAfterLines = 40; pCell.SpacingBeforeLines = 40; //放入单元格table.GetRow(4).GetCell(1).SetParagraph(pCell);

      表格中换行
      var run= paragraph.CreateRun(); run.SetText(contends[i]); run.FontSize = 11; run.SetFontFamily("宋体", FontCharRange.None); run.AddBreak(BreakType.TEXTWRAPPING); //换行

      合并单元格
      table.GetRow(rowIndex).MergeCells(fromCol, toCol); //合并列

      水平合并行单元格
      CT_Tc cttcofRowThird = cell.GetCTTc(); CT_TcPr ctProfRowThird = cttcofRowThird.AddNewTcPr(); ctProfRowThird.gridSpan = new CT_DecimalNumber(); ctProfRowThird.gridSpan.val = num.ToString(); //合并num列

      合并行、垂直合并列单元格
      public void MYMergeRows(XWPFTable table, int fromRow, int toRow, int colIndex){for (int rowIndex = fromRow; rowIndex <= toRow; rowIndex++){XWPFTableCell rowcell = table.GetRow(rowIndex).GetCell(colIndex); rowcell.SetVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER); CT_Tc cttc = rowcell.GetCTTc(); CT_TcPr ctTcPr = cttc.tcPr; if (ctTcPr == null){ctTcPr = cttc.AddNewTcPr(); }if (rowIndex == fromRow){// The first merged cell is set with RESTART merge valuectTcPr.AddNewVMerge().val = ST_Merge.restart; }else{// Cells which join (merge) the first one, are set with CONTINUEctTcPr.AddNewVMerge().val = ST_Merge.@continue; //继续合并行}ctTcPr.AddNewVAlign().val = ST_VerticalJc.center; //垂直}}


      5、页眉页脚处理
      XWPFDocument doc = new XWPFDocument(); doc.Document.body.sectPr = new CT_SectPr(); CT_SectPr m_SectPr = doc.Document.body.sectPr; //创建页眉CT_Hdr m_Hdr = new CT_Hdr(); CT_P m_P = m_Hdr.AddNewP(); m_P.AddNewR().AddNewT().Value = "https://www.it610.com/article/页眉内容值"; m_P.AddNewPPr().AddNewJc().val = ST_Jc.center; // 页眉居中//创建页眉关系(headern.xml)XWPFRelation Hrelation = XWPFRelation.HEADER; XWPFHeader m_h = (XWPFHeader)doc.CreateRelationship(Hrelation, XWPFFactory.GetInstance(), doc.HeaderList.Count + 1); doc.CreateFootnotes(); //设置页眉m_h.SetHeaderFooter(m_Hdr); CT_HdrFtrRef m_HdrFtr = m_SectPr.AddNewHeaderReference(); m_h.GetRelationById(m_HdrFtr.id); //创建页脚CT_Ftr m_ftr = new CT_Ftr(); CT_P m_fP = m_ftr.AddNewP(); m_fP.AddNewR().AddNewT().Value = "https://www.it610.com/article/页脚内容值"; m_fP.AddNewPPr().AddNewJc().val = ST_Jc.center; // 页眉居中//创建页脚关系(footern.xml)XWPFRelation Frelation = XWPFRelation.FOOTER; XWPFFooter m_f = (XWPFFooter)doc.CreateRelationship(Frelation, XWPFFactory.GetInstance(), doc.FooterList.Count + 1); //设置页脚m_f.SetHeaderFooter(m_ftr); m_HdrFtr = m_SectPr.AddNewFooterReference(); m_HdrFtr.type = ST_HdrFtr.@default; m_f.GetRelationById(m_HdrFtr.id);


      三、综合示例
      CT_SectPr srcpr = new CT_SectPr(); //设置A4纸纵向,如果要横向,两个值调换即可srcpr.pgSz.w = (ulong)11906; srcpr.pgSz.h = (ulong)16838; XWPFDocument doc = new XWPFDocument(); doc.Document.body.sectPr = srcpr; //输出标题XWPFParagraph ptitle = doc.CreateParagraph(); ptitle.Alignment = ParagraphAlignment.CENTER; XWPFRun titlerun = ptitle.CreateRun(); //向该段落中添加文字titlerun.SetText("标题"); titlerun.IsBold = true; titlerun.FontFamily = "华文行楷"; titlerun.FontSize = 30; titlerun.SetColor("blue"); //输出一个段落XWPFParagraph p2 = doc.CreateParagraph(); p2.Alignment = ParagraphAlignment.CENTER; p2.IndentationFirstLine = (int)100; //首行缩进XWPFRun r2 = p2.CreateRun(); r2.SetText(string.Format("生成时间:{0}", DateTime.Now.ToString("yyyy-MM-dd HH:mm"))); r2.FontSize = 15; titlerun.FontFamily = "宋体"; StringBuilder sb = new StringBuilder(); using (FileStream stream = File.OpenRead("simple.docx")){XWPFDocument docx = new XWPFDocument(stream); //页眉foreach (XWPFHeader xwpfHeader in docx.HeaderList){sb.AppendLine(string.Format("{0}", new string[] { xwpfHeader.Text })); }//页脚foreach (XWPFFooter xwpfFooter in docx.FooterList){sb.AppendLine(string.Format("{0}", new string[] { xwpfFooter.Text })); }//读取段落foreach (var para in docx.Paragraphs){string text = para.ParagraphText; //获得文本var runs = para.Runs; // string styleid = para.Style; for (int i = 0; i < runs.Count; i++){var run = runs[i]; text = run.ToString(); //获得run的文本sb.Append(text + ","); }}//读取表格foreach (XWPFTable table in docx.Tables){//循环表格行foreach (XWPFTableRow row in table.Rows){foreach (XWPFTableCell cell in row.GetTableCells()){sb.Append(cell.GetText()); }}}//读取图片foreach (XWPFPictureData pictureData in docx.AllPictures){string picExtName = pictureData.SuggestFileExtension(); string picFileName = pictureData.FileName; byte[] picFileContent = pictureData.Data; string picTempName = string.Format(Guid.NewGuid().ToString() + "_" + picFileName + "." + picExtName); using (FileStream fs = new FileStream(picTempName, FileMode.Create, FileAccess.Write)){fs.Write(picFileContent, 0, picFileContent.Length); fs.Close(); }sb.AppendLine(picTempName); }Console.WriteLine(sb.ToString()); }FileStream out1 = new FileStream("simple.docx", FileMode.Create); doc.Write(out1); out1.Close();


      四、参考 Word与Excel字号对照表
      C#使用NPOI对word进行读写
      文章图片

      到此这篇关于C#使用NPOI对word进行读写的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

        推荐阅读