C# 生成word文档(NPOI.XWPF)
一、基础
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文件夹,然后使用相对路径访问。
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)的更多相关文章
- PoiDocxDemo【Android将表单数据生成Word文档的方案之二(基于Poi4.0.0),目前只能java生成】
版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 这个是<PoiDemo[Android将表单数据生成Word文档的方案之二(基于Poi4.0.0)]>的扩展,上一篇是根 ...
- PoiDemo【Android将表单数据生成Word文档的方案之二(基于Poi4.0.0)】
版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 使用Poi实现android中根据模板文件生成Word文档的功能.这里的模板文件是doc文件.如果模板文件是docx文件的话,请阅读 ...
- Aspose.Words简单生成word文档
Aspose.Words简单生成word文档 Aspose.Words.Document doc = new Aspose.Words.Document(); Aspose.Words.Documen ...
- ASP.NET生成WORD文档,服务器部署注意事项
网上转的,留查备用,我服务器装的office2007所以修改的是Microsoft Office word97 - 2003 文档这一个. ASP.NET生成WORD文档服务器部署注意事项 1.Asp ...
- POI生成WORD文档
h2:first-child, body>h1:first-child, body>h1:first-child+h2, body>h3:first-child, body>h ...
- PowerDesigner将PDM导出生成WORD文档
PowerDesigner将PDM导出生成WORD文档 环境 PowerDesigner15 1.点击Report Temlates 制作模板 2.如果没有模板,单击New图标创建.有直接双击进入. ...
- velocity模板技术生成word文档
本文介绍採用velocity技术在Java中生成word文档的方法. 1.新建一个word文档,编辑内容例如以下: 2.将上述word文档另存为htm格式的文件 3.新建一个Java Project项 ...
- 使用C#动态生成Word文档/Excel文档的程序测试通过后,部署到IIS服务器上,不能正常使用的问题解决方案
使用C#动态生成Word文档/Excel文档的程序功能调试.测试通过后,部署到服务器上,不能正常使用的问题解决方案: 原因: 可能asp.net程序或iis访问excel组件时权限不够(Ps:Syst ...
- 用php生成word文档
一.用windows里面自带的com,然后用php生成word文档 <?php $word= new COM("word.application") or die(" ...
- c#生成word文档
参考:http://blog.163.com/zhouchunping_99/blog/static/7837998820085114394716/ 生成word文档 生成word文档 view pl ...
随机推荐
- Ubuntu Server下MySql数据库备份脚本代码
明: 我这里要把MySql数据库存放目录/var/lib/mysql下面的pw85数据库备份到/home/mysql_data里面,并且保存为mysqldata_bak_2012_04_11.tar. ...
- SpringBoot---事务支持
1.自动配置的事务管理器 1.1.使用JDBC 作为 数据访问技术 时,SpringBoot 为我们 定义了 PlatformTransactionManager的实现 DataSourc ...
- Linux命令行工具之pidstat命令
原创转载请注明出处:https://www.cnblogs.com/agilestyle/p/11484624.html pidstat命令就可以帮助我们监测到具体线程的上下文切换 通过pidstat ...
- NIO拷贝
- 实现粘贴WORD图片的在线编辑器
我司需要做一个需求,就是使用富文本编辑器时,不要以上传附件的形式上传图片,而是以复制粘贴的形式上传图片. 在网上找了一下,有一个插件支持这个功能. WordPaster 安装方式如下: 直接使用Wor ...
- Power Strings POJ - 2406
Power Strings POJ - 2406 时限: 3000MS 内存: 65536KB 64位IO格式: %I64d & %I64u 提交 状态 已开启划词翻译 问题描述 Gi ...
- html from表单异步处理
from表单异步处理. 简单处理方法: jQuery做异步提交表单处理, 通过$("#form").serialize()将表单元素的数据转化为字符串, 最后通过$.ajax()执 ...
- django缓存优化(二)
一.缓存目的: 1.减小过载 2.避免重复计算 3.提高系统性能 二.如何进行缓存 三.缓存类型 四.缓存粒度分类 五.缓存的设置与使用 示例一: CACHES = { 'default': { 'B ...
- MySql使用mysqldump 导入与导出方法总结
导出数据库数据:首先打开cmd进入MySQL的bin文件夹下 1.导出education数据库里面的users表的表数据和表结构(下面以users表为例) mysqldump -u[用户名] -h[i ...
- 【TestNG】TestNG使用教程详解
一.TestNG介绍TestNG是Java中的一个测试框架, 类似于JUnit 和NUnit, 功能都差不多, 只是功能更加强大,使用也更方便.详细使用说明请参考官方链接:https://testng ...