一、基础

1、创建Word

using NPOI.XWPF.UserModelXWPFDocument doc = new XWPFDocument();      //创建新的word文档
        XWPFParagraph p1 = doc.CreateParagraph();   //向新文档中添加段落p1.SetAlignment(ParagraphAlignment.CENTER); //段落对其方式为居中
XWPFRun r1 = p1.CreateRun();                //向该段落中添加文字r1.SetText("测试段落一");XWPFParagraph p2 = doc.CreateParagraph();p2.SetAlignment(ParagraphAlignment.LEFT);XWPFRun r2 = p2.CreateRun();r2.SetText("测试段落二");r2.SetFontSize(16);//设置字体大小r2.SetBlod(true);//设置粗体
FileStream sw = File.Create("cutput.docx"); //...doc.Write(sw);                              //...sw.Close();                                 //在服务端生成文件
FileInfo file = new FileInfo("cutput.docx");//文件保存路径及名称  //注意: 文件保存的父文件夹需添加Everyone用户,并给予其完全控制权限
        Response.Clear();Response.ClearHeaders();Response.Buffer = false;Response.ContentType = "application/octet-stream";Response.AppendHeader("Content-Disposition", "attachment;filename=" + HttpUtility.UrlEncode("output.docx", System.Text.Encoding.UTF8));Response.AppendHeader("Content-Length", file.Length.ToString());Response.WriteFile(file.FullName);Response.Flush();                           //以上将生成的word文件发送至用户浏览器
File.Delete("cutput.docx");

2、特殊字符

代码实现起来很简单。

run之前的代码就不写了。大家可以网上搜索。

run.FontFamily = "Wingdings 2";//这边是特殊字符的字体
text = text.Replace("name", Convert.ToChar(0x0052).ToString());//0x0052是特殊字符的十六进制代码//text = text.Replace("name", "R");//该代码也可以实现(0x0052对应的字符就是R)

3、NOPI读取Word模板并渲染保存

using NPOI.XWPF.UserModel;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Web;namespace TestNPOI
{public class NPOIHleper{public static void Export(){string filepath = HttpContext.Current.Server.MapPath("~/simpleTable.docx");var tt = new  { name = "cjc", age = 29 };using (FileStream stream = File.OpenRead(filepath)){XWPFDocument doc = new XWPFDocument(stream);//遍历段落                  foreach (var para in doc.Paragraphs){ReplaceKey(para, tt);}                    //遍历表格      var tables = doc.Tables;foreach (var table in tables){foreach (var row in table.Rows){foreach (var cell in row.GetTableCells()){foreach (var para in cell.Paragraphs){ReplaceKey(para, tt);}}}}FileStream out1 = new FileStream(HttpContext.Current.Server.MapPath("~/simpleTable" + DateTime.Now.Ticks + ".docx"), FileMode.Create);doc.Write(out1);out1.Close();}}private static void ReplaceKey(XWPFParagraph para, object model){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();Type t = model.GetType();PropertyInfo[] pi = t.GetProperties();foreach (PropertyInfo p in pi){//$$与模板中$$对应,也可以改成其它符号,比如{$name},务必做到唯一if (text.Contains("$" + p.Name + "$")){text = text.Replace("$" + p.Name + "$", p.GetValue(model, null).ToString());}}runs[i].SetText(text, 0);}}}
}

 

模板:

结果:

二、实践(渲染Word模板、插入特殊字符、指定表格位置插入行)

1、项目搭建

1、创建项目

2、创建类库和引入NPOI

报错

报搜尝试解决方案一

在项目下面建立upload文件夹,然后使用相对路径访问。

在其他目录下请把upload目录权限授予asp.net用户。
最后直接暴力EveryOney  也无效,找到的原因是参数位置搞错了,文件名+路径最后改为 路径+文件名的方式

3、贴上代码

using NPOI.XWPF.UserModel;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Web;namespace NPOITest
{public class NPOIHleper{/// <summary>/// 输出模板docx文档/// </summary>/// <param name="tempFilePath">模板文件地址</param>/// <param name="outFolder">输出文件夹</param >/// <param name="fileName">文件名</param>/// <param name="data">数据格式Json->new { name = "cjc", age = 29 }</param>public static void CreateWord(string tempFilePath, string outFolder, string fileName, object data){using (FileStream stream = File.OpenRead(tempFilePath)){XWPFDocument doc = new XWPFDocument(stream);//遍历段落                  foreach (var para in doc.Paragraphs){ReplaceKey(para, data);}   //遍历表格      var tables = doc.Tables;foreach (var table in tables){foreach (var row in table.Rows){foreach (var cell in row.GetTableCells()){foreach (var para in cell.Paragraphs){ReplaceKey(para, data);}}}}var fullPath = Path.Combine(outFolder, fileName);FileStream outFile = new FileStream(fullPath, FileMode.Create);doc.Write(outFile);outFile.Close();}}/// <summary>/// 遍历替换段落位置字符/// </summary>/// <param name="para">段落参数</param>/// <param name="model">数据</param>private static void ReplaceKey(XWPFParagraph para, object model){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();Type t = model.GetType();PropertyInfo[] pi = t.GetProperties();foreach (PropertyInfo p in pi){//$$与模板中$$对应,也可以改成其它符号,比如{$name},务必做到唯一if (text.Contains("{$"+p.Name+"}")){text = text.Replace("{$" + p.Name+"}", p.GetValue(model, null).ToString());}}runs[i].SetText(text, 0);}}}
}

调用方式

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;namespace NPOITest.Controllers
{public class HomeController : Controller{public ActionResult Index(){var  data = new  { name = "cjc", age = 29 };string fileName = Guid.NewGuid() + "_声明.docx";string folder = Server.MapPath("~/upload"); //当前运行环境string tempTemplateFile = folder+"/测试.docx";string folders = "D:\\TempFile"; //当前运行环境
            NPOIHleper.CreateWord(tempTemplateFile, folders, fileName, data);//
            ViewBag.Title = "Home Page";return View();}}
}

对应模板

三、实践(指定表格位置插入行)

代码:

using NPOI.OpenXmlFormats.Wordprocessing;
using NPOI.XWPF.UserModel;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Web;namespace NPOITest
{public class NPOIHleper{/// <summary>/// 输出模板docx文档/// </summary>/// <param name="tempFilePath">模板文件地址</param>/// <param name="outFolder">输出文件夹</param >/// <param name="fileName">文件名</param>/// <param name="data">数据格式Json->new { name = "cjc", age = 29 }</param>public static void CreateWord(string tempFilePath, string outFolder, string fileName, object data){using (FileStream stream = File.OpenRead(tempFilePath)){XWPFDocument doc = new XWPFDocument(stream);//遍历段落                  foreach (var para in doc.Paragraphs){ReplaceKey(para, data);}   //遍历表格      var tables = doc.Tables;foreach (var table in tables){foreach (var row in table.Rows){foreach (var cell in row.GetTableCells()){foreach (var para in cell.Paragraphs){ReplaceKey(para, data);}}}}//单独对表格新增var oprTable = tables[1];XWPFTableRow m_Row=oprTable.InsertNewTableRow(1);//创建一行/并且在某个位置添加一行m_Row.AddNewTableCell().SetText ("创建一行仅有一个单元格");//XWPFTableRow m_Row2 = oprTable.InsertNewTableRow(2);//创建一行/并且在某个位置添加一行////m_Row2.AddNewTableCell().SetText("添加的新行");//XWPFTableCell cellCt_P = m_Row2.CreateCell();//创建一个单元格,创建单元格时就创建了一个CT_P//cellCt_P = m_Row2.CreateCell();//cellCt_P = m_Row2.CreateCell();////单元格行和表//CT_Tc cttc = cellCt_P.GetCTTc();//CT_TcPr ctPr = cttc.AddNewTcPr();////ctPr.gridSpan.val = "3";//合并3列//ctPr.AddNewVMerge().val = ST_Merge.restart;//合并行//cellCt_P.SetText("创建一行仅有一个单元格(合并后)");
XWPFTableRow m_Row2 = oprTable.InsertNewTableRow(2);//创建一行/并且在某个位置添加一行XWPFTableCell tc3 = m_Row2.CreateCell();//创建单元格tc3.SetText("创建一行仅有一个单元格(合并后)");CT_Tc ct3 = tc3.GetCTTc();CT_TcPr cp3 = ct3.AddNewTcPr();cp3.gridSpan = new CT_DecimalNumber();cp3.gridSpan.val = "3"; //合并3列
XWPFTableRow m_Row3 = oprTable.InsertNewTableRow(2);//多个单元格以及合并m_Row3.AddNewTableCell().SetText("添加的新行单元格1");m_Row3.AddNewTableCell().SetText("添加的新行单元格2");m_Row3.AddNewTableCell().SetText("添加的新行单元格3");var fullPath = Path.Combine(outFolder, fileName);FileStream outFile = new FileStream(fullPath, FileMode.Create);doc.Write(outFile);outFile.Close();}}/// <summary>/// 遍历替换段落位置字符/// </summary>/// <param name="para">段落参数</param>/// <param name="model">数据</param>private static void ReplaceKey(XWPFParagraph para, object model){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();Type t = model.GetType();PropertyInfo[] pi = t.GetProperties();foreach (PropertyInfo p in pi){//$$与模板中$$对应,也可以改成其它符号,比如{$name},务必做到唯一if (text.Contains("{$" + p.Name + "}")){text = text.Replace("{$" + p.Name + "}", p.GetValue(model, null).ToString());}}runs[i].SetText(text, 0);}}}
}

结果:

四、实践(指定表格内单元格(字体)下划线+字符)

简单说明:

                XWPFParagraph p1 = doc.CreateParagraph(); //段落XWPFRun _run = p1.CreateRun();_run.SetText("一个单元格");_run.SetUnderline(UnderlinePatterns.Single);//段落下划线

既有文字加文字(下划线)

                XWPFTableRow m_Row2 = oprTable.InsertNewTableRow(2);//创建一行/并且在某个位置添加一行XWPFTableCell tc3 = m_Row2.CreateCell();//创建单元格//tc3.SetText("创建一行仅有一个单元格(合并后)");
XWPFParagraph p1 = doc.CreateParagraph(); //段落XWPFRun _run = p1.CreateRun();_run.SetText("一个单元格");_run.SetUnderline(UnderlinePatterns.Single);//段落
XWPFParagraph p12 = doc.CreateParagraph(); //无段落XWPFRun _run2 = p1.CreateRun();_run2.SetText("一个单元格");tc3.SetParagraph(p1);

这种写法我发现别扭,应该为

                //单独对表格新增var oprTable = tables[1];XWPFTableRow m_Row2 = oprTable.InsertNewTableRow(2);//创建一行/并且在某个位置添加一行XWPFTableCell tc3 = m_Row2.CreateCell();//创建单元格XWPFParagraph p1 = doc.CreateParagraph(); //段落1开始  1、注意这个段落是Doc创建的会导致表格外有段落出现XWPFRun _run = p1.CreateRun();_run.SetText("下划线");_run.SetUnderline(UnderlinePatterns.Single);//段落1结束//_run.AddCarriageReturn();2、注意只对表格外换行有效XWPFRun _run2 = p1.CreateRun();_run2.SetText("#####");tc3.SetParagraph(p1);

  发现我需要换行,思路还是不对,经过我读取拿到文档的数据结构,即表格的XWPFTableCell单元格paragraph属性如下:

经更改

                //单独对表格新增var oprTable = tables[1];XWPFTableRow m_Row2 = oprTable.InsertNewTableRow(2);//创建一行/并且在某个位置添加一行XWPFTableCell tc3 = m_Row2.CreateCell();//创建单元格
XWPFParagraph p1 = tc3.AddParagraph();XWPFRun _run = p1.CreateRun();_run.SetText("下划线");_run.SetUnderline(UnderlinePatterns.Single);//段落1结束//_run.AddCarriageReturn();2、注意只对表格外换行有效XWPFParagraph p2 = tc3.AddParagraph();XWPFRun _run2 = p2.CreateRun();_run2.SetText("####");//这里设置了一下 //在复制这个就无效了 tc3.SetParagraph(p1); 想要添加通过(add方式)tc3.AddParagraph();tc3.SetParagraph(p1);

五、实践出现模板渲染替换问题

解决办法:删掉->重新写->可以从记事本复制

其他妙用

//新建段落     

XWPFParagraph p1 = doc.CreateParagraph();//对齐方式
p1.SetAlignment(ParagraphAlignment.LEFT);p1.SetVerticalAlignment(TextAlignment.AUTO);//Word边框样式

p1.SetBorderBottom(Borders.DOUBLE);
p1.SetBorderTop(Borders.DOUBLE);
p1.SetBorderRight(Borders.DOUBLE);
p1.SetBorderLeft(Borders.DOUBLE);p1.SetBorderBetween(Borders.SINGLE);//新建文字
XWPFRun rUserHead = p1.CreateRun();//文字内容
rUserHead.SetText("员工 : ");//颜色
rUserHead.SetColor("4F6B72");//大小
rUserHead.SetFontSize(15);//是否加粗
rUserHead.SetBold(true);//字体
rUserHead.SetFontFamily("宋体");//是否有下划线//r1.SetUnderline(UnderlinePatterns.DotDotDash);//位置
rUserHead.SetTextPosition(20);//增加换行

rUserHead.AddCarriageReturn();

需求整理(动态在某个单元格内插入多个字段)

1、原本样子以及要实现的效果

实现的效果

原因:

需求整理(动态插入表格)

1、原本样子以及要实现的效果

转载于:https://www.cnblogs.com/fger/p/11187954.html

C# 生成word文档(NPOI.XWPF)相关推荐

  1. Sql Server 生成 Word 文档 表结构

    打开数据库编辑器,输入以下代码并执行(F5) SELECT--表名 = case when a.colorder=1 then d.name else '' end,--表说明 = case when ...

  2. NPOI 生成word文档

    后端接口 /// <summary>/// 根据id导出 生成word文档/// </summary>/// <param name="ID"> ...

  3. PoiDocxDemo【Android将表单数据生成Word文档的方案之二(基于Poi4.0.0),目前只能java生成】...

    版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 这个是<PoiDemo[Android将表单数据生成Word文档的方案之二(基于Poi4.0.0)]>的扩展,上一篇是根 ...

  4. POI生成word文档,包括标题,段落,表格,统计图(非图片格式)

    Apache POI 是用Java编写的免费开源的跨平台的 Java API,Apache POI提供API给Java程式对Microsoft Office格式档案读和写的功能.POI为"P ...

  5. poi生成word文档,插入图片,echar报表生成到word,word表格

    poi生成word文档,word表格,将echar报表生成到word 项目中用到生成word报表,报表中有表格的合并 .页眉.表格中会有报表图片.然后查找了网上的资料,利用echar生成柱状图,然后已 ...

  6. php导出doc文件_PHP生成Word文档的方法

    PHP生成Word文档的方法 首先,请确保在你的Windows系统中已经安装并配置好了一个典型的WAMP环境.由于Interop纯粹是一个Windows的特性,我们将在Windows平台下搭建Apac ...

  7. php 内容自动生成word文档,php生成word文档的例子

    /** * 生成word文档 * * @param string $html 内容部分 * @param string $file 文件名称 * @param string $code 当前文件编码, ...

  8. 将HTML导出生成word文档

    前言: 项目开发中遇到了需要将HTML页面的内容导出为一个word文档,所以有了这边随笔. 当然,项目开发又时间有点紧迫,第一时间想到的是用插件,所以百度了下.下面就介绍两个导出word文档的方法. ...

  9. 用Aspose.Words for .NET动态生成word文档中的图片或水印

    1.概述 在项目中生成word文档,这个功能很普遍的,一般生成都是纯文字或是列表的比较多,便于客户打印,而要把图片也生成到word文档中的需求有些客户也是需要的,例如产品图片.这次我们介绍的是如何利用 ...

  10. python读取word指定内容_python解析html提取数据,并生成word文档实例解析

    简介 今天试着用ptyhon做了一个抓取网页内容,并生成word文档的功能,功能很简单,做一下记录以备以后用到. 生成word用到了第三方组件python-docx,所以先进行第三方组件的安装.由于w ...

最新文章

  1. Android应用程序获得root权限
  2. github 慢_告别github 下载慢问题,让你的github下载速度起飞
  3. Java黑皮书课后题第6章:*6.38(生成随机字符)使用程序清单6-10 RandomCharacter中的方法,打印100个大写字母及100个一位数字,每行打印10个
  4. JavaEE Tutorials (17) - Java消息服务示例
  5. python 中如何判断list中是否包含某个元素
  6. 关于jquery find 获取不到 input标签问题
  7. 如何在VScode 中 调试 ts 文件 Unit test
  8. IOS开发之实现App消息推送(最新)
  9. RabbitMQ入门(2)--工作队列
  10. Windows下启动Apache报错:ServerRoot must be a valid directory
  11. Packet Tracer 5.0实验(二) 交换机的Telnet远程登录设置
  12. 有的数字不适合作版本号
  13. python:sklearn 标签编码(LabelEncoder)
  14. Windows下创建TFTP服务器,uboot访问,下载镜像
  15. Pr 视频效果:过时
  16. Telink/BDT使用说明
  17. 固态硬盘安装系统时显示,windows无法完成格式化解决办法。
  18. 两个一维数组合成二维数组
  19. 网易云音乐在 Ubuntu 下缩放的问题
  20. 【iOS】应用跳转到系统应用

热门文章

  1. eclipse下载支持compiler compliance level 1.8的插件
  2. LINUX使用sed完成文本文件的修改
  3. 解码H264帧要注意的两个问题
  4. THAAD反导必将部署,各方已接受事实
  5. 一个盒子两个摄像头,你就不知道怎么办了?
  6. 系统调用之Write
  7. 日期格式 java_Java时间日期格式转换
  8. VC++ 只运行一个程序实例
  9. python壁纸4k_别人用钱,而我用python爬虫爬取了一年的4K高清壁纸!真实用!
  10. 单价数量和总价的公式_小学数学量的计算单位及常用公式表