一、基础

1、创建Word

using NPOI.XWPF.UserModel
XWPFDocument 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();//设置字体大小
       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 = };
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 = ; 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, );
}
} }
}

 

模板:

结果:

二、实践(渲染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 = ; 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, );
}
}
}
}

调用方式

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 = };
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[]; XWPFTableRow m_Row=oprTable.InsertNewTableRow();//创建一行/并且在某个位置添加一行
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();//创建一行/并且在某个位置添加一行
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列 XWPFTableRow m_Row3 = oprTable.InsertNewTableRow();//多个单元格以及合并
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 = ; 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, );
}
}
}
}

结果:

 

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

简单说明:

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

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

                XWPFTableRow m_Row2 = oprTable.InsertNewTableRow();//创建一行/并且在某个位置添加一行
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[]; XWPFTableRow m_Row2 = oprTable.InsertNewTableRow();//创建一行/并且在某个位置添加一行
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(); //是否加粗 rUserHead.SetBold(true); //字体 rUserHead.SetFontFamily("宋体"); //是否有下划线 //r1.SetUnderline(UnderlinePatterns.DotDotDash); //位置 rUserHead.SetTextPosition(); //增加换行 rUserHead.AddCarriageReturn();

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

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

实现的效果

原因:

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

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

C# 生成word文档(NPOI.XWPF)的更多相关文章

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

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

  2. PoiDemo【Android将表单数据生成Word文档的方案之二(基于Poi4.0.0)】

    版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 使用Poi实现android中根据模板文件生成Word文档的功能.这里的模板文件是doc文件.如果模板文件是docx文件的话,请阅读 ...

  3. Aspose.Words简单生成word文档

    Aspose.Words简单生成word文档 Aspose.Words.Document doc = new Aspose.Words.Document(); Aspose.Words.Documen ...

  4. ASP.NET生成WORD文档,服务器部署注意事项

    网上转的,留查备用,我服务器装的office2007所以修改的是Microsoft Office word97 - 2003 文档这一个. ASP.NET生成WORD文档服务器部署注意事项 1.Asp ...

  5. POI生成WORD文档

    h2:first-child, body>h1:first-child, body>h1:first-child+h2, body>h3:first-child, body>h ...

  6. PowerDesigner将PDM导出生成WORD文档

    PowerDesigner将PDM导出生成WORD文档 环境 PowerDesigner15 1.点击Report Temlates 制作模板 2.如果没有模板,单击New图标创建.有直接双击进入. ...

  7. velocity模板技术生成word文档

    本文介绍採用velocity技术在Java中生成word文档的方法. 1.新建一个word文档,编辑内容例如以下: 2.将上述word文档另存为htm格式的文件 3.新建一个Java Project项 ...

  8. 使用C#动态生成Word文档/Excel文档的程序测试通过后,部署到IIS服务器上,不能正常使用的问题解决方案

    使用C#动态生成Word文档/Excel文档的程序功能调试.测试通过后,部署到服务器上,不能正常使用的问题解决方案: 原因: 可能asp.net程序或iis访问excel组件时权限不够(Ps:Syst ...

  9. 用php生成word文档

    一.用windows里面自带的com,然后用php生成word文档 <?php $word= new COM("word.application") or die(" ...

  10. c#生成word文档

    参考:http://blog.163.com/zhouchunping_99/blog/static/7837998820085114394716/ 生成word文档 生成word文档 view pl ...

随机推荐

  1. Ubuntu Server下MySql数据库备份脚本代码

    明: 我这里要把MySql数据库存放目录/var/lib/mysql下面的pw85数据库备份到/home/mysql_data里面,并且保存为mysqldata_bak_2012_04_11.tar. ...

  2. SpringBoot---事务支持

    1.自动配置的事务管理器 1.1.使用JDBC  作为 数据访问技术  时,SpringBoot  为我们  定义了  PlatformTransactionManager的实现  DataSourc ...

  3. Linux命令行工具之pidstat命令

    原创转载请注明出处:https://www.cnblogs.com/agilestyle/p/11484624.html pidstat命令就可以帮助我们监测到具体线程的上下文切换 通过pidstat ...

  4. NIO拷贝

  5. 实现粘贴WORD图片的在线编辑器

    我司需要做一个需求,就是使用富文本编辑器时,不要以上传附件的形式上传图片,而是以复制粘贴的形式上传图片. 在网上找了一下,有一个插件支持这个功能. WordPaster 安装方式如下: 直接使用Wor ...

  6. Power Strings POJ - 2406

    Power Strings POJ - 2406 时限: 3000MS   内存: 65536KB   64位IO格式: %I64d & %I64u 提交 状态 已开启划词翻译 问题描述 Gi ...

  7. html from表单异步处理

    from表单异步处理. 简单处理方法: jQuery做异步提交表单处理, 通过$("#form").serialize()将表单元素的数据转化为字符串, 最后通过$.ajax()执 ...

  8. django缓存优化(二)

    一.缓存目的: 1.减小过载 2.避免重复计算 3.提高系统性能 二.如何进行缓存 三.缓存类型 四.缓存粒度分类 五.缓存的设置与使用 示例一: CACHES = { 'default': { 'B ...

  9. MySql使用mysqldump 导入与导出方法总结

    导出数据库数据:首先打开cmd进入MySQL的bin文件夹下 1.导出education数据库里面的users表的表数据和表结构(下面以users表为例) mysqldump -u[用户名] -h[i ...

  10. 【TestNG】TestNG使用教程详解

    一.TestNG介绍TestNG是Java中的一个测试框架, 类似于JUnit 和NUnit, 功能都差不多, 只是功能更加强大,使用也更方便.详细使用说明请参考官方链接:https://testng ...