Net5使用NPOI创建World模板
前言
最近需要集成上上签,完成类似在线签约合同的需求,需要传入附件,本来一开始想创建PDF的,但是有很多限制,而且没有找到成熟的方案,项目框架也是Net5,受制于框架,就想到了NPOI。
1.NPOI
1.1Nuget
NPOI支持还蛮多的
项目直接引用,版本根据自己的项目框架决定
第一种方式:
NET CLi
dotnet add package NPOI --version 2.6.2-rc1
第二种方式:
PM> NuGet\Install-Package NPOI -Version 2.6.2-rc1
2.World模板
这个模板可以根据接口返回的数据自动填充的
可以写一个返回测试数据的JSON串的方法,方便后面测试遍历
3.创建标题
首先创建一个XWPFDocument,设置它的大小为A4
XWPFDocument document = new XWPFDocument();
CT_SectPr cT_SectPr = new CT_SectPr();
//页面大小
//A4(纵向):W=11906 H=16838
//A4(横向):W = 16838 H = 11906
//A5 : W = 8390 H = 11906
//A6 : W = 5953 H = 8390
cT_SectPr.pgSz.h = (ulong)16838;
cT_SectPr.pgSz.w = (ulong)11906;
////页面边距
//cT_SectPr.pgMar.left = (ulong)10;//左边距
//cT_SectPr.pgMar.right = (ulong)10;//右边距
//cT_SectPr.pgMar.top = (ulong)10;//上边距
//cT_SectPr.pgMar.bottom = (ulong)10;//下边距
document.Document.body.sectPr = cT_SectPr;
document.SetParagraph(NpoiWordParagraphTextStyleHelper._.ParagraphInstanceSetting(document, "这是标题", true, 12, "微软雅黑", ParagraphAlignment.CENTER), 0);
ParagraphInstanceSetting方法
先创建一个段落对象,在创建一个段落文本对象,这个方法支持俩个段落文本对象,也可以自己扩展
/// <summary>
/// 创建word文档中的段落对象和设置段落文本的基本样式(字体大小,字体,字体颜色,字体对齐位置)
/// </summary>
/// <param name="document">document文档对象</param>
/// <param name="fillContent">段落第一个文本对象填充的内容</param>
/// <param name="isBold">是否加粗</param>
/// <param name="fontSize">字体大小</param>
/// <param name="fontFamily">字体</param>
/// <param name="paragraphAlign">段落排列(左对齐,居中,右对齐)</param>
/// <param name="isStatement">是否在同一段落创建第二个文本对象(解决同一段落里面需要填充两个或者多个文本值的情况,多个文本需要自己拓展,现在最多支持两个)</param>
/// <param name="secondFillContent">第二次声明的文本对象填充的内容,样式与第一次的一致</param>
/// <param name="fontColor">字体颜色--十六进制</param>
/// <param name="isItalic">是否设置斜体(字体倾斜)</param>
/// <returns></returns>
public XWPFParagraph ParagraphInstanceSetting(XWPFDocument document, string fillContent, bool isBold, int fontSize, string fontFamily, ParagraphAlignment paragraphAlign, bool isStatement = false, string secondFillContent = "", string fontColor = "000000", bool isItalic = false)
{
XWPFParagraph paragraph = document.CreateParagraph();//创建段落对象
paragraph.Alignment = paragraphAlign;//文字显示位置,段落排列(左对齐,居中,右对齐)
XWPFRun xwpfRun = paragraph.CreateRun();//创建段落文本对象
xwpfRun.IsBold = isBold;//文字加粗
xwpfRun.SetText(fillContent);//填充内容
xwpfRun.FontSize = fontSize;//设置文字大小
xwpfRun.IsItalic = isItalic;//是否设置斜体(字体倾斜)
xwpfRun.SetColor(fontColor);//设置字体颜色--十六进制
xwpfRun.SetFontFamily(fontFamily, FontCharRange.None); //设置标题样式如:(微软雅黑,隶书,楷体)根据自己的需求而定
if (!isStatement) return paragraph;
XWPFRun secondXwpfRun = paragraph.CreateRun();//创建段落文本对象
secondXwpfRun.IsBold = isBold;//文字加粗
secondXwpfRun.SetText(secondFillContent);//填充内容
secondXwpfRun.FontSize = fontSize;//设置文字大小
secondXwpfRun.IsItalic = isItalic;//是否设置斜体(字体倾斜)
secondXwpfRun.SetColor(fontColor);//设置字体颜色--十六进制
secondXwpfRun.SetFontFamily(fontFamily, FontCharRange.None); //设置标题样式如:(微软雅黑,隶书,楷体)根据自己的需求而定
return paragraph;
}
4.创建段落对象和文本对象
第二行创建了一个段落对象,但是创建了6个文本对象,因为有三个是动态的且不需要加粗的
分开创建文本对象的代码:
XWPFParagraph paragraph = document.CreateParagraph();//创建段落对象
NpoiWordParagraphTextStyleHelper._.ParagraphInstanceSettingExtend(paragraph, "期间:", true, 10, "微软雅黑", ParagraphAlignment.LEFT);
NpoiWordParagraphTextStyleHelper._.ParagraphInstanceSettingExtend(paragraph, "第一个参数", false, 10, "微软雅黑", ParagraphAlignment.LEFT);
NpoiWordParagraphTextStyleHelper._.ParagraphInstanceSettingExtend(paragraph, " 客户联系人:", true, 10, "微软雅黑", ParagraphAlignment.LEFT);
NpoiWordParagraphTextStyleHelper._.ParagraphInstanceSettingExtend(paragraph, "第二个参数", false, 10, "微软雅黑", ParagraphAlignment.LEFT);
NpoiWordParagraphTextStyleHelper._.ParagraphInstanceSettingExtend(paragraph, " 客户联系电话:", true, 10, "微软雅黑", ParagraphAlignment.LEFT);
NpoiWordParagraphTextStyleHelper._.ParagraphInstanceSettingExtend(paragraph, "第三个参数", false, 10, "微软雅黑", ParagraphAlignment.LEFT);
公共代码:
/// <summary>
/// 创建word文档中的段落对象和设置段落文本的基本样式(字体大小,字体,字体颜色,字体对齐位置)
/// </summary>
/// <param name="paragraph">document文档对象</param>
/// <param name="fillContent">段落第一个文本对象填充的内容</param>
/// <param name="isBold">是否加粗</param>
/// <param name="fontSize">字体大小</param>
/// <param name="fontFamily">字体</param>
/// <param name="paragraphAlign">段落排列(左对齐,居中,右对齐)</param>
/// <param name="fontColor">字体颜色--十六进制</param>
/// <param name="isItalic">是否设置斜体(字体倾斜)</param>
public void ParagraphInstanceSettingExtend(XWPFParagraph paragraph, string fillContent, bool isBold, int fontSize, string fontFamily, ParagraphAlignment paragraphAlign, string fontColor = "000000", bool isItalic = false)
{
//XWPFParagraph paragraph = document.CreateParagraph();//创建段落对象
paragraph.Alignment = paragraphAlign;//文字显示位置,段落排列(左对齐,居中,右对齐)
XWPFRun xwpfRun = paragraph.CreateRun();//创建段落文本对象
xwpfRun.IsBold = isBold;//文字加粗
xwpfRun.SetText(fillContent);//填充内容
xwpfRun.FontSize = fontSize;//设置文字大小
xwpfRun.IsItalic = isItalic;//是否设置斜体(字体倾斜)
xwpfRun.SetColor(fontColor);//设置字体颜色--十六进制
xwpfRun.SetFontFamily(fontFamily, FontCharRange.None); //设置标题样式如:(微软雅黑,隶书,楷体)根据自己的需求而定
}
5.创建表格
5.1创建表格 设置列宽
设置表格水平居中,需要用到CT_Tbl。
我一开始设置列宽不好使,最后查阅资料需要用到CT_TblLayoutType。
tblLayout 这个属性 默认值是 autofit 这里需要设置为 fixed 将自动改为固定宽
table.GetCTTbl().AddNewTblPr().tblLayout = new CT_TblLayoutType() { type = ST_TblLayoutType.@fixed };
如果NPOI版本过低,没有GetCTTbl ,可以通过反射。
var tableType = table.GetType();
FieldInfo fieldInfo = tableType.GetField("ctTbl", BindingFlags.NonPublic | BindingFlags.Instance);
表格标题的背景色只能每个单元格的设置,没找到其他一次设置的方法。
然后就是设置标题加粗。
表格代码:
// 第三行:数据表格
var rows = jsonData["Detail"].Count() + 1;
XWPFTable dataXwpfTable = document.CreateTable(rows, 5);//显示的行列数rows行,cols:5列
// 表格水平居中
CT_Tbl cT_Tbl = document.Document.body.getTblArray()[0];
cT_Tbl.AddNewTblPr().jc = new CT_Jc
{
val = ST_Jc.center
};
// 列宽
dataXwpfTable.GetCTTbl().AddNewTblPr().tblLayout = new CT_TblLayoutType() { type = ST_TblLayoutType.@fixed };
dataXwpfTable.Width = 6500;
dataXwpfTable.SetColumnWidth(0, 1200); /* 设置列宽 */
dataXwpfTable.SetColumnWidth(1, 2300); /* 设置列宽 */
dataXwpfTable.SetColumnWidth(2, 1000); /* 设置列宽 */
dataXwpfTable.SetColumnWidth(3, 1000); /* 设置列宽 */
dataXwpfTable.SetColumnWidth(4, 1000); /* 设置列宽 */
// 表格标题背景色
var colArr = new List<short> { 0, 1, 2, 3, 4 };
colArr.ForEach(colIndex => { dataXwpfTable.GetRow(0).GetCell(colIndex).SetColor("DDEBF7"); });
// 表格标题
dataXwpfTable.GetRow(0).GetCell(0).SetParagraph(NpoiWordParagraphTextStyleHelper._.SetTableParagraphInstanceSetting(document, dataXwpfTable, $"日期", ParagraphAlignment.CENTER, "微软雅黑", 25, true, 10));
dataXwpfTable.GetRow(0).GetCell(1).SetParagraph(NpoiWordParagraphTextStyleHelper._.SetTableParagraphInstanceSetting(document, dataXwpfTable, "摘要", ParagraphAlignment.CENTER, "微软雅黑", 25, true, 10));
dataXwpfTable.GetRow(0).GetCell(2).SetParagraph(NpoiWordParagraphTextStyleHelper._.SetTableParagraphInstanceSetting(document, dataXwpfTable, "货款金额", ParagraphAlignment.CENTER, "微软雅黑", 25, true, 10));
dataXwpfTable.GetRow(0).GetCell(3).SetParagraph(NpoiWordParagraphTextStyleHelper._.SetTableParagraphInstanceSetting(document, dataXwpfTable, "收款金额", ParagraphAlignment.CENTER, "微软雅黑", 25, true, 10));
dataXwpfTable.GetRow(0).GetCell(4).SetParagraph(NpoiWordParagraphTextStyleHelper._.SetTableParagraphInstanceSetting(document, dataXwpfTable, "余额", ParagraphAlignment.CENTER, "微软雅黑", 25, true, 10));
int rowIndex = 1;
公共方法:
/// <summary>
/// 创建Word文档中表格段落实例和设置表格段落文本的基本样式(字体大小,字体,字体颜色,字体对齐位置)
/// </summary>
/// <param name="document">document文档对象</param>
/// <param name="table">表格对象</param>
/// <param name="fillContent">要填充的文字</param>
/// <param name="paragraphAlign">段落排列(左对齐,居中,右对齐)</param>
/// <param name="textPosition">设置文本位置(设置两行之间的行间,从而实现表格文字垂直居中的效果),从而实现table的高度设置效果 </param>
/// <param name="isBold">是否加粗(true加粗,false不加粗)</param>
/// <param name="fontSize">字体大小</param>
/// <param name="fontColor">字体颜色--十六进制</param>
/// <param name="isItalic">是否设置斜体(字体倾斜)</param>
/// <returns></returns>
public XWPFParagraph SetTableParagraphInstanceSetting(XWPFDocument document, XWPFTable table, string fillContent, ParagraphAlignment paragraphAlign, string fontFamily, int textPosition = 24, bool isBold = false, int fontSize = 10, string fontColor = "000000", bool isItalic = false)
{
var para = new CT_P();
//设置单元格文本对齐
para.AddNewPPr().AddNewTextAlignment();
XWPFParagraph paragraph = new XWPFParagraph(para, table.Body);//创建表格中的段落对象
paragraph.Alignment = paragraphAlign;//文字显示位置,段落排列(左对齐,居中,右对齐)
//paragraph.FontAlignment =Convert.ToInt32(ParagraphAlignment.CENTER);//字体在单元格内显示位置与 paragraph.Alignment效果相似
paragraph.VerticalAlignment = TextAlignment.CENTER;
paragraph.SpacingAfterLines = textPosition;//下方距离
paragraph.SpacingBeforeLines = textPosition;//上方距离
//paragraph.FillBackgroundColor = backColor; // "DDEBF7";
//设置文本高度(行间距)
//paragraph.TextPosition = 120;
XWPFRun xwpfRun = paragraph.CreateRun();//创建段落文本对象
xwpfRun.SetText(fillContent);//设置文本位置(设置两行之间的行间),从而实现table的高度设置效果
xwpfRun.FontSize = fontSize;//字体大小
xwpfRun.SetColor(fontColor);//设置字体颜色--十六进制
xwpfRun.IsItalic = isItalic;//是否设置斜体(字体倾斜)
xwpfRun.IsBold = isBold;//是否加粗
xwpfRun.SetFontFamily(fontFamily, FontCharRange.None);//设置字体(如:微软雅黑,华文楷体,宋体)
//xwpfRun.SetTextPosition(textPosition);//设置文本位置(设置两行之间的行间),从而实现table的高度设置效果
//xwpfRun.GetCTR().AddNewRPr().AddNewShd().fill = backColor;
return paragraph;
}
5.2动态添加表体
我这里测试数据传的是JObject,可以通过[]获取值
表格代码,公共方法和5.1一样,后面会全部贴出
int rowIndex = 1;
foreach (var data in jsonData["Detail"])
{
if (!data["ViewDate"].ToString().Contains("本期欠款金额"))
{
dataXwpfTable.GetRow(rowIndex).GetCell(0).SetParagraph(NpoiWordParagraphTextStyleHelper._.SetTableParagraphInstanceSetting(document, dataXwpfTable, data["ViewDate"].ToString(), ParagraphAlignment.LEFT, "微软雅黑", 25, false, 10));
dataXwpfTable.GetRow(rowIndex).GetCell(1).SetParagraph(NpoiWordParagraphTextStyleHelper._.SetTableParagraphInstanceSetting(document, dataXwpfTable, data["Abstract"].ToString(), ParagraphAlignment.LEFT, "微软雅黑", 25, false, 10));
decimal.TryParse(data["DebitAmount"].ToString(), out decimal debitAmount);
dataXwpfTable.GetRow(rowIndex).GetCell(2).SetParagraph(NpoiWordParagraphTextStyleHelper._.SetTableParagraphInstanceSetting(document, dataXwpfTable, string.Format("{0:C}", debitAmount).Replace("¥", ""), ParagraphAlignment.RIGHT, "微软雅黑", 25, false, 10));
decimal.TryParse(data["CreditAmount"].ToString(), out decimal creditAmount);
dataXwpfTable.GetRow(rowIndex).GetCell(3).SetParagraph(NpoiWordParagraphTextStyleHelper._.SetTableParagraphInstanceSetting(document, dataXwpfTable, string.Format("{0:C}", creditAmount).Replace("¥", ""), ParagraphAlignment.RIGHT, "微软雅黑", 25, false, 10));
decimal.TryParse(data["DebitTotalAmount"].ToString(), out decimal debitTotalAmount);
dataXwpfTable.GetRow(rowIndex).GetCell(4).SetParagraph(NpoiWordParagraphTextStyleHelper._.SetTableParagraphInstanceSetting(document, dataXwpfTable, string.Format("{0:C}", debitTotalAmount).Replace("¥", ""), ParagraphAlignment.RIGHT, "微软雅黑", 25, false, 10));
}
else
{
dataXwpfTable.GetRow(rowIndex).GetCell(0).SetParagraph(NpoiWordParagraphTextStyleHelper._.SetTableParagraphInstanceSetting(document, dataXwpfTable, data["ViewDate"].ToString(), ParagraphAlignment.LEFT, "微软雅黑", 25, false, 10));
dataXwpfTable.GetRow(rowIndex).MergeCells(1, 4);//合并4列
dataXwpfTable.GetRow(rowIndex).GetCell(1).SetParagraph(NpoiWordParagraphTextStyleHelper._.SetTableParagraphInstanceSetting(document, dataXwpfTable, data["Abstract"].ToString(), ParagraphAlignment.RIGHT, "微软雅黑", 25, false, 10));
}
rowIndex++;
}
6.创建完成
本来写的是API接口,为了避坑,先写了个控制台程序
string dire = System.AppDomain.CurrentDomain.BaseDirectory + "Files";
// 判断目录是否存在,不存在则创建
if (!Directory.Exists(dire))
{
Directory.CreateDirectory(dire);
}
// 文件保存
using (var stream = new FileStream(Path.Combine(dire, "测试" + DateTime.UtcNow.Ticks.ToString() + ".docx"), FileMode.Create))
{
document.Write(stream);
}
document.Close();
document.Dispose();
Console.WriteLine("生成完成");
7.完整代码
NPOI公共代码
public class NpoiWordParagraphTextStyleHelper
{
private static NpoiWordParagraphTextStyleHelper _exportHelper;
public static NpoiWordParagraphTextStyleHelper _
{
get => _exportHelper ?? (_exportHelper = new NpoiWordParagraphTextStyleHelper());
set => _exportHelper = value;
}
/// <summary>
/// 创建word文档中的段落对象和设置段落文本的基本样式(字体大小,字体,字体颜色,字体对齐位置)
/// </summary>
/// <param name="document">document文档对象</param>
/// <param name="fillContent">段落第一个文本对象填充的内容</param>
/// <param name="isBold">是否加粗</param>
/// <param name="fontSize">字体大小</param>
/// <param name="fontFamily">字体</param>
/// <param name="paragraphAlign">段落排列(左对齐,居中,右对齐)</param>
/// <param name="isStatement">是否在同一段落创建第二个文本对象(解决同一段落里面需要填充两个或者多个文本值的情况,多个文本需要自己拓展,现在最多支持两个)</param>
/// <param name="secondFillContent">第二次声明的文本对象填充的内容,样式与第一次的一致</param>
/// <param name="fontColor">字体颜色--十六进制</param>
/// <param name="isItalic">是否设置斜体(字体倾斜)</param>
/// <returns></returns>
public XWPFParagraph ParagraphInstanceSetting(XWPFDocument document, string fillContent, bool isBold, int fontSize, string fontFamily, ParagraphAlignment paragraphAlign, bool isStatement = false, string secondFillContent = "", string fontColor = "000000", bool isItalic = false)
{
XWPFParagraph paragraph = document.CreateParagraph();//创建段落对象
paragraph.Alignment = paragraphAlign;//文字显示位置,段落排列(左对齐,居中,右对齐)
XWPFRun xwpfRun = paragraph.CreateRun();//创建段落文本对象
xwpfRun.IsBold = isBold;//文字加粗
xwpfRun.SetText(fillContent);//填充内容
xwpfRun.FontSize = fontSize;//设置文字大小
xwpfRun.IsItalic = isItalic;//是否设置斜体(字体倾斜)
xwpfRun.SetColor(fontColor);//设置字体颜色--十六进制
xwpfRun.SetFontFamily(fontFamily, FontCharRange.None); //设置标题样式如:(微软雅黑,隶书,楷体)根据自己的需求而定
if (!isStatement) return paragraph;
XWPFRun secondXwpfRun = paragraph.CreateRun();//创建段落文本对象
secondXwpfRun.IsBold = isBold;//文字加粗
secondXwpfRun.SetText(secondFillContent);//填充内容
secondXwpfRun.FontSize = fontSize;//设置文字大小
secondXwpfRun.IsItalic = isItalic;//是否设置斜体(字体倾斜)
secondXwpfRun.SetColor(fontColor);//设置字体颜色--十六进制
secondXwpfRun.SetFontFamily(fontFamily, FontCharRange.None); //设置标题样式如:(微软雅黑,隶书,楷体)根据自己的需求而定
return paragraph;
}
/// <summary>
/// 创建Word文档中表格段落实例和设置表格段落文本的基本样式(字体大小,字体,字体颜色,字体对齐位置)
/// </summary>
/// <param name="document">document文档对象</param>
/// <param name="table">表格对象</param>
/// <param name="fillContent">要填充的文字</param>
/// <param name="paragraphAlign">段落排列(左对齐,居中,右对齐)</param>
/// <param name="textPosition">设置文本位置(设置两行之间的行间,从而实现表格文字垂直居中的效果),从而实现table的高度设置效果 </param>
/// <param name="isBold">是否加粗(true加粗,false不加粗)</param>
/// <param name="fontSize">字体大小</param>
/// <param name="fontColor">字体颜色--十六进制</param>
/// <param name="isItalic">是否设置斜体(字体倾斜)</param>
/// <returns></returns>
public XWPFParagraph SetTableParagraphInstanceSetting(XWPFDocument document, XWPFTable table, string fillContent, ParagraphAlignment paragraphAlign, int textPosition = 24, bool isBold = false, int fontSize = 10, string fontColor = "000000", bool isItalic = false)
{
var para = new CT_P();
//设置单元格文本对齐
para.AddNewPPr().AddNewTextAlignment();
XWPFParagraph paragraph = new XWPFParagraph(para, table.Body);//创建表格中的段落对象
paragraph.Alignment = paragraphAlign;//文字显示位置,段落排列(左对齐,居中,右对齐)
//paragraph.FontAlignment =Convert.ToInt32(ParagraphAlignment.CENTER);//字体在单元格内显示位置与 paragraph.Alignment效果相似
XWPFRun xwpfRun = paragraph.CreateRun();//创建段落文本对象
xwpfRun.SetText(fillContent, textPosition);//设置文本位置(设置两行之间的行间),从而实现table的高度设置效果
xwpfRun.FontSize = fontSize;//字体大小
xwpfRun.SetColor(fontColor);//设置字体颜色--十六进制
xwpfRun.IsItalic = isItalic;//是否设置斜体(字体倾斜)
xwpfRun.IsBold = isBold;//是否加粗
xwpfRun.SetFontFamily("宋体", FontCharRange.None);//设置字体(如:微软雅黑,华文楷体,宋体)
//xwpfRun.SetTextPosition(textPosition);//设置文本位置(设置两行之间的行间),从而实现table的高度设置效果
return paragraph;
}
/// <summary>
/// 创建Word文档中表格段落实例和设置表格段落文本的基本样式(字体大小,字体,字体颜色,字体对齐位置)
/// </summary>
/// <param name="document">document文档对象</param>
/// <param name="table">表格对象</param>
/// <param name="fillContent">要填充的文字</param>
/// <param name="paragraphAlign">段落排列(左对齐,居中,右对齐)</param>
/// <param name="textPosition">设置文本位置(设置两行之间的行间,从而实现表格文字垂直居中的效果),从而实现table的高度设置效果 </param>
/// <param name="isBold">是否加粗(true加粗,false不加粗)</param>
/// <param name="fontSize">字体大小</param>
/// <param name="fontColor">字体颜色--十六进制</param>
/// <param name="isItalic">是否设置斜体(字体倾斜)</param>
/// <returns></returns>
public XWPFParagraph SetTableParagraphInstanceSetting(XWPFDocument document, XWPFTable table, string fillContent, ParagraphAlignment paragraphAlign, string fontFamily, int textPosition = 24, bool isBold = false, int fontSize = 10, string fontColor = "000000", bool isItalic = false)
{
var para = new CT_P();
//设置单元格文本对齐
para.AddNewPPr().AddNewTextAlignment();
XWPFParagraph paragraph = new XWPFParagraph(para, table.Body);//创建表格中的段落对象
paragraph.Alignment = paragraphAlign;//文字显示位置,段落排列(左对齐,居中,右对齐)
//paragraph.FontAlignment =Convert.ToInt32(ParagraphAlignment.CENTER);//字体在单元格内显示位置与 paragraph.Alignment效果相似
paragraph.VerticalAlignment = TextAlignment.CENTER;
paragraph.SpacingAfterLines = textPosition;//下方距离
paragraph.SpacingBeforeLines = textPosition;//上方距离
//paragraph.FillBackgroundColor = backColor; // "DDEBF7";
//设置文本高度(行间距)
//paragraph.TextPosition = 120;
XWPFRun xwpfRun = paragraph.CreateRun();//创建段落文本对象
xwpfRun.SetText(fillContent);//设置文本位置(设置两行之间的行间),从而实现table的高度设置效果
xwpfRun.FontSize = fontSize;//字体大小
xwpfRun.SetColor(fontColor);//设置字体颜色--十六进制
xwpfRun.IsItalic = isItalic;//是否设置斜体(字体倾斜)
xwpfRun.IsBold = isBold;//是否加粗
xwpfRun.SetFontFamily(fontFamily, FontCharRange.None);//设置字体(如:微软雅黑,华文楷体,宋体)
//xwpfRun.SetTextPosition(textPosition);//设置文本位置(设置两行之间的行间),从而实现table的高度设置效果
//xwpfRun.GetCTR().AddNewRPr().AddNewShd().fill = backColor;
return paragraph;
}
/// <summary>
/// 创建word文档中的段落对象和设置段落文本的基本样式(字体大小,字体,字体颜色,字体对齐位置)
/// </summary>
/// <param name="document">document文档对象</param>
/// <param name="fillContent">段落第一个文本对象填充的内容</param>
/// <param name="isBold">是否加粗</param>
/// <param name="fontSize">字体大小</param>
/// <param name="fontFamily">字体</param>
/// <param name="paragraphAlign">段落排列(左对齐,居中,右对齐)</param>
/// <param name="isStatement">是否在同一段落创建第二个文本对象(解决同一段落里面需要填充两个或者多个文本值的情况,多个文本需要自己拓展,现在最多支持两个)</param>
/// <param name="secondFillContent">第二次声明的文本对象填充的内容,样式与第一次的一致</param>
/// <param name="fontColor">字体颜色--十六进制</param>
/// <param name="isItalic">是否设置斜体(字体倾斜)</param>
/// <returns></returns>
public void ParagraphInstanceSettingExtend(XWPFParagraph paragraph, string fillContent, bool isBold, int fontSize, string fontFamily, ParagraphAlignment paragraphAlign, bool isStatement = false, string fontColor = "000000", bool isItalic = false)
{
//XWPFParagraph paragraph = document.CreateParagraph();//创建段落对象
paragraph.Alignment = paragraphAlign;//文字显示位置,段落排列(左对齐,居中,右对齐)
XWPFRun xwpfRun = paragraph.CreateRun();//创建段落文本对象
xwpfRun.IsBold = isBold;//文字加粗
xwpfRun.SetText(fillContent);//填充内容
xwpfRun.FontSize = fontSize;//设置文字大小
xwpfRun.IsItalic = isItalic;//是否设置斜体(字体倾斜)
xwpfRun.SetColor(fontColor);//设置字体颜色--十六进制
xwpfRun.SetFontFamily(fontFamily, FontCharRange.None); //设置标题样式如:(微软雅黑,隶书,楷体)根据自己的需求而定
}
}
表格代码(出于安全考虑我把测试json串给删掉了,自己添加测试的json数据就行了):
static void Main(string[] args)
{
XWPFDocument document = new XWPFDocument();
CT_SectPr cT_SectPr = new CT_SectPr();
//页面大小
//A4(纵向):W=11906 H=16838
//A4(横向):W = 16838 H = 11906
//A5 : W = 8390 H = 11906
//A6 : W = 5953 H = 8390
cT_SectPr.pgSz.h = (ulong)16838;
cT_SectPr.pgSz.w = (ulong)11906;
////页面边距
//cT_SectPr.pgMar.left = (ulong)10;//左边距
//cT_SectPr.pgMar.right = (ulong)10;//右边距
//cT_SectPr.pgMar.top = (ulong)10;//上边距
//cT_SectPr.pgMar.bottom = (ulong)10;//下边距
document.Document.body.sectPr = cT_SectPr;
document.SetParagraph(NpoiWordParagraphTextStyleHelper._.ParagraphInstanceSetting(document, "对账明细", true, 12, "微软雅黑", ParagraphAlignment.CENTER), 0);
XWPFParagraph paragraph = document.CreateParagraph();//创建段落对象
NpoiWordParagraphTextStyleHelper._.ParagraphInstanceSettingExtend(paragraph, "期间:", true, 10, "微软雅黑", ParagraphAlignment.LEFT);
NpoiWordParagraphTextStyleHelper._.ParagraphInstanceSettingExtend(paragraph, "2022-12-01~2023-05-26", false, 10, "微软雅黑", ParagraphAlignment.LEFT);
NpoiWordParagraphTextStyleHelper._.ParagraphInstanceSettingExtend(paragraph, " 客户联系人:", true, 10, "微软雅黑", ParagraphAlignment.LEFT);
NpoiWordParagraphTextStyleHelper._.ParagraphInstanceSettingExtend(paragraph, "参数1", false, 10, "微软雅黑", ParagraphAlignment.LEFT);
NpoiWordParagraphTextStyleHelper._.ParagraphInstanceSettingExtend(paragraph, " 客户联系电话:", true, 10, "微软雅黑", ParagraphAlignment.LEFT);
NpoiWordParagraphTextStyleHelper._.ParagraphInstanceSettingExtend(paragraph, "参数2", false, 10, "微软雅黑", ParagraphAlignment.LEFT);
var jsonData = getJsonData();
// 数据表格
var rows = jsonData["Detail"].Count() + 1;
XWPFTable dataXwpfTable = document.CreateTable(rows, 5);//显示的行列数rows:5行,cols:7列
// 表格水平居中
CT_Tbl cT_Tbl = document.Document.body.getTblArray()[0];
cT_Tbl.AddNewTblPr().jc = new CT_Jc();
cT_Tbl.AddNewTblPr().jc.val = ST_Jc.center;
// 列宽
dataXwpfTable.GetCTTbl().AddNewTblPr().tblLayout = new CT_TblLayoutType() { type = ST_TblLayoutType.@fixed };
dataXwpfTable.Width = 6500;
dataXwpfTable.SetColumnWidth(0, 1200); /* 设置列宽 */
dataXwpfTable.SetColumnWidth(1, 2300); /* 设置列宽 */
dataXwpfTable.SetColumnWidth(2, 1000); /* 设置列宽 */
dataXwpfTable.SetColumnWidth(3, 1000); /* 设置列宽 */
dataXwpfTable.SetColumnWidth(4, 1000); /* 设置列宽 */
// 第一行背景色
dataXwpfTable.GetRow(0).GetCell(0).SetColor("DDEBF7");
dataXwpfTable.GetRow(0).GetCell(1).SetColor("DDEBF7");
dataXwpfTable.GetRow(0).GetCell(2).SetColor("DDEBF7");
dataXwpfTable.GetRow(0).GetCell(3).SetColor("DDEBF7");
dataXwpfTable.GetRow(0).GetCell(4).SetColor("DDEBF7");
dataXwpfTable.GetRow(0).GetCell(0).SetParagraph(NpoiWordParagraphTextStyleHelper._.SetTableParagraphInstanceSetting(document, dataXwpfTable, $"第一列", ParagraphAlignment.CENTER, "微软雅黑", 25, true, 10));
dataXwpfTable.GetRow(0).GetCell(1).SetParagraph(NpoiWordParagraphTextStyleHelper._.SetTableParagraphInstanceSetting(document, dataXwpfTable, "第二列", ParagraphAlignment.CENTER, "微软雅黑", 25, true, 10));
dataXwpfTable.GetRow(0).GetCell(2).SetParagraph(NpoiWordParagraphTextStyleHelper._.SetTableParagraphInstanceSetting(document, dataXwpfTable, "第三列", ParagraphAlignment.CENTER, "微软雅黑", 25, true, 10));
dataXwpfTable.GetRow(0).GetCell(3).SetParagraph(NpoiWordParagraphTextStyleHelper._.SetTableParagraphInstanceSetting(document, dataXwpfTable, "第四列", ParagraphAlignment.CENTER, "微软雅黑", 25, true, 10));
dataXwpfTable.GetRow(0).GetCell(4).SetParagraph(NpoiWordParagraphTextStyleHelper._.SetTableParagraphInstanceSetting(document, dataXwpfTable, "第五列", ParagraphAlignment.CENTER, "微软雅黑", 25, true, 10));
int rowIndex = 1;
foreach (var data in jsonData["Detail"])
{
if (!data["ViewDate"].ToString().Contains("本期欠款金额"))
{
dataXwpfTable.GetRow(rowIndex).GetCell(0).SetParagraph(NpoiWordParagraphTextStyleHelper._.SetTableParagraphInstanceSetting(document, dataXwpfTable, data[""].ToString(), ParagraphAlignment.LEFT, "微软雅黑", 25, false, 10));
dataXwpfTable.GetRow(rowIndex).GetCell(1).SetParagraph(NpoiWordParagraphTextStyleHelper._.SetTableParagraphInstanceSetting(document, dataXwpfTable, data[""].ToString(), ParagraphAlignment.LEFT, "微软雅黑", 25, false, 10));
decimal.TryParse(data[""].ToString(),out decimal debitAmount);
dataXwpfTable.GetRow(rowIndex).GetCell(2).SetParagraph(NpoiWordParagraphTextStyleHelper._.SetTableParagraphInstanceSetting(document, dataXwpfTable, string.Format("{0:C}", debitAmount).Replace("¥", ""), ParagraphAlignment.RIGHT, "微软雅黑", 25, false, 10));
decimal.TryParse(data[""].ToString(), out decimal creditAmount);
dataXwpfTable.GetRow(rowIndex).GetCell(3).SetParagraph(NpoiWordParagraphTextStyleHelper._.SetTableParagraphInstanceSetting(document, dataXwpfTable, string.Format("{0:C}", creditAmount).Replace("¥",""), ParagraphAlignment.RIGHT, "微软雅黑", 25, false, 10));
decimal.TryParse(data[""].ToString(), out decimal debitTotalAmount);
dataXwpfTable.GetRow(rowIndex).GetCell(4).SetParagraph(NpoiWordParagraphTextStyleHelper._.SetTableParagraphInstanceSetting(document, dataXwpfTable, string.Format("{0:C}", ).Replace("¥", ""), ParagraphAlignment.RIGHT, "微软雅黑", 25, false, 10));
}
else
{
dataXwpfTable.GetRow(rowIndex).GetCell(0).SetParagraph(NpoiWordParagraphTextStyleHelper._.SetTableParagraphInstanceSetting(document, dataXwpfTable, data["ViewDate"].ToString(), ParagraphAlignment.LEFT, "微软雅黑", 25, false, 10));
dataXwpfTable.GetRow(rowIndex).MergeCells(1, 4);//合并4列
dataXwpfTable.GetRow(rowIndex).GetCell(1).SetParagraph(NpoiWordParagraphTextStyleHelper._.SetTableParagraphInstanceSetting(document, dataXwpfTable, data["Abstract"].ToString(), ParagraphAlignment.RIGHT, "微软雅黑", 25, false, 10));
}
rowIndex++;
}
string dire = System.AppDomain.CurrentDomain.BaseDirectory + "Files";
// 判断目录是否存在,不存在则创建
if (!Directory.Exists(dire))
{
Directory.CreateDirectory(dire);
}
// 文件保存
using (var stream = new FileStream(Path.Combine(dire, "测试" + DateTime.UtcNow.Ticks.ToString() + ".docx"), FileMode.Create))
{
document.Write(stream);
}
document.Close();
document.Dispose();
Console.WriteLine("生成完成");
}
static JObject getJsonData()
{
string jsonstr = "";
return JObject.Parse(jsonstr);
}
8.API接口
如果想使用API接口调用,改一下返回参数即可
8.1后端
创建完成后写入Stream,可以转换成byte,也可不转换,通过File对象,支持byte[]和Stream
using MemoryStream stream = new();
document.Write(stream);
byte[] bytes = stream.ToArray();
document.Close();
document.Dispose();
return await Task.FromResult<byte[]>(bytes);
自己的测试数据传进去生成world,返回File。
AllowAnonymous设置不需要权限,负责前端调用就需要传token。
Controller:
[HttpGet]
[Route("bbb/CreateWorld/{key}")]
[AllowAnonymous]
public async Task<FileResult> CreateWrold([FromServices] Provider provider, string key)
{
var xxx = provider.GetDetail(key.ToLong());
var bytes = await _xxxProvider.CreateWrold(JObject.FromObject(xxx));
return File(bytes, "application/octet-stream", "测试.docx");
}
8.2前端
创建a标签,实现调用
downloadfile() {
// world
let date = new Date();
//const fileName = '测试.docx';
const link = document.createElement('a'); // 创建a标签
//link.download = fileName; // a标签添加属性
link.style.display = 'none';
link.href =`http://localhost:9008/api/aaa/bbb/CreateWorld/${this.data.id}`;
document.body.appendChild(link);
link.click(); // 执行下载
URL.revokeObjectURL(link.href); // 释放url
document.body.removeChild(link); // 释放标签
}
9.总结
前前后后做了俩三天,查看了很多资料,遇到了很多问题,也算顺利,总结一下,希望帮助大家。
10.参考
.NET Core使用NPOI导出复杂Word详解:
https://www.cnblogs.com/Can-daydayup/p/11588531.html
.NET Core使用NPOI导出复杂Word详解
https://www.cnblogs.com/Can-daydayup/p/11588531.html
.NET Core使用NPOI将Excel中的数据批量导入到MySQL
https://www.cnblogs.com/Can-daydayup/p/12593165.html
NPOI关于 WORD 中 TABLE 的列宽设置
https://www.cnblogs.com/lixi12138/p/15090179.html
Word文档导出之NPOI (.Net core6.0)
https://www.cnblogs.com/ZhuMeng-Chao/p/17074271.html
创作不易,如果感觉帮助到你了,还请多多支持,我会继续努力。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析