NPOI生成word浮动图标

1、NPOI版本2.7.0, net框架4.8

2、安装OpenXMLSDKToolV25.msi

3、先创建一个word文档,并设置图片为浮于文字之上

4、OpenXML显示的结果

5、实际代码如下:

public class GenerateWordDemo
{
	public GenerateWordDemo()
	{
	}

	//https://blog.fileformat.com/zh/word-processing/npoi-api-for-processing-word-documents-in-net-an-overview/
	//https://blog.csdn.net/sD7O95O/article/details/114108985
	//https://blog.csdn.net/qq_38544249/article/details/124923848

	private void SetPage(XWPFDocument doc)
	{
		// 设置页面的大小
		CT_SectPr m_SectPr = new CT_SectPr();       //实例一个尺寸类的实例
		m_SectPr.pgSz.w = 11906;        //设置宽度(这里是一个ulong类型)
		m_SectPr.pgSz.h = 16838;        //设置高度(这里是一个ulong类型)                    
										//页面边距
		m_SectPr.pgMar.left = (ulong)80;//左边距
		m_SectPr.pgMar.right = (ulong)80;//右边距
		m_SectPr.pgMar.top = 80;//上边距
		m_SectPr.pgMar.bottom = 80;//下边距

		doc.Document.body.sectPr = m_SectPr;          //设置页面的尺寸
	}

	/// <summary>
	/// 加入内联二维码
	/// </summary>
	/// <param name="doc"></param>
	/// <param name="paragraphy"></param>
	private void AddInlineBarCode(XWPFDocument doc, XWPFParagraph paragraphy)
	{
		string appPath = System.AppDomain.CurrentDomain.BaseDirectory;
		string imagePath = System.IO.Path.Combine(appPath, "Images");
		string imageFile = System.IO.Path.Combine(imagePath, "BarCode.jpg");

		// 二维码            
		XWPFRun run = paragraphy.CreateRun();
		using (FileStream picFile = new FileStream(imageFile, FileMode.Open, FileAccess.Read))
		{
			XWPFPicture pic = run.AddPicture(picFile, (int)PictureType.PNG, "barcode.png", 100 * 10857, 100 * 12857);
		}
	}

	private T LoadWordCT<T>(string xml, Func<XmlElement, T> act) where T : class
	{
		XmlDocument xmlDoc = new XmlDocument();
		try
		{
			xmlDoc.LoadXml(xml);
			var element = xmlDoc.DocumentElement;
			return act(element);                
		}
		catch (XmlException xe)
		{
			return null;
		}
	}

	/// <summary>
	/// 加入二维码
	/// </summary>
	/// <param name="doc"></param>
	private void AddBarCode(XWPFDocument doc, XWPFParagraph paragraphy)
	{
		String relationId;
		XWPFPictureData picData;
		string appPath = System.AppDomain.CurrentDomain.BaseDirectory;
		string imagePath = System.IO.Path.Combine(appPath, "Images");
		string imageFile = System.IO.Path.Combine(imagePath, "BarCode.jpg");

		using (FileStream picFile = new FileStream(imageFile, FileMode.Open, FileAccess.Read))
		{
			relationId = doc.AddPictureData(picFile, (int)PictureType.PNG);
			picData = (XWPFPictureData)doc.GetRelationById(relationId);
		}
   
		XWPFRun run = paragraphy.CreateRun();
		CT_RPr rpr = new CT_RPr();
		rpr.AddNewNoProof();
		run.GetCTR().rPr = rpr;
		CT_Drawing drawing = run.GetCTR().AddNewDrawing();

		drawing.anchor = new List<CT_Anchor>();
		CT_Anchor an = new CT_Anchor();            
		//图片距正文上(distT)、下(distB)、左(distL)、右(distR)的距离。114300EMUS=3.1mm
		an.distT = 0;
		an.distB = 0;
		an.distL = (uint)114300;
		an.distR = (uint)114300;
		an.relativeHeight = 251658240u;
		an.behindDoc = false; //"0",图与文字的上下关系
		an.locked = false;  //"0"
		an.layoutInCell = true;  //"1"
		an.allowOverlap = true;  //"1" 
		an.simplePos1 = false;
		an.simplePos1Specified = false;

		//CT_Point2D simplePos = new CT_Point2D();
		//simplePos.x = (long)0;
		//simplePos.y = (long)0;
		//an.simplePos = simplePos;

		// https://www.cnblogs.com/zhangliming/archive/2013/04/02/2995655.html
		string xml = "<wp:simplePos x=\"0\" y=\"0\" xmlns:wp=\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\" />";
		an.simplePos = LoadWordCT<CT_Point2D>(xml, x => CT_Point2D.Parse(x, null));

		//图左上角坐标
		CT_PosH posH = new CT_PosH();
		posH.relativeFrom = ST_RelFromH.column;
		posH.posOffset = -1292;   //单位:EMUS,1CM=360000EMUS
		an.positionH = posH;

		CT_PosV posV = new CT_PosV();
		posV.relativeFrom = ST_RelFromV.paragraph;
		posV.posOffset = 51661;
		an.positionV = posV;

		an.extent = new NPOI.OpenXmlFormats.Dml.WordProcessing.CT_PositiveSize2D();
		an.extent.cx = 1085700;
		an.extent.cy = 1285700;

		CT_EffectExtent effectExtent = new CT_EffectExtent();
		effectExtent.b = 0L;
		effectExtent.l = 0L;
		effectExtent.r = 0L;
		effectExtent.t = 0L;
		an.effectExtent = effectExtent;
		an.wrapNone = new CT_WrapNone();

		an.docPr = new NPOI.OpenXmlFormats.Dml.WordProcessing.CT_NonVisualDrawingProps();
		long id = run.Document.GetNextPicNameNumber((int)PictureType.PNG);
		an.docPr.id = (uint)(id);
		an.docPr.name = ("Drawing " + id);
		an.docPr.descr = "barcode.png";
		an.cNvGraphicFramePr = new NPOI.OpenXmlFormats.Dml.WordProcessing.CT_NonVisualGraphicFrameProperties();

		an.graphic = new CT_GraphicalObject();
		CT_GraphicalObjectData gd = new CT_GraphicalObjectData();
		gd.uri = "http://schemas.openxmlformats.org/drawingml/2006/picture";
		an.graphic.graphicData = gd;

		// Grab the picture object
		NPOI.OpenXmlFormats.Dml.Picture.CT_Picture pic = new NPOI.OpenXmlFormats.Dml.Picture.CT_Picture();

		// Set it up
		NPOI.OpenXmlFormats.Dml.Picture.CT_PictureNonVisual nvPicPr = pic.AddNewNvPicPr();

		NPOI.OpenXmlFormats.Dml.CT_NonVisualDrawingProps cNvPr = nvPicPr.AddNewCNvPr();
		/* use "0" for the id. See ECM-576, 20.2.2.3 */
		cNvPr.id = (0);
		/* This name is not visible in Word 2010 anywhere */
		cNvPr.name = ("Picture " + id);
		cNvPr.descr = "barcode.png";

		CT_NonVisualPictureProperties cNvPicPr = nvPicPr.AddNewCNvPicPr();
		cNvPicPr.AddNewPicLocks().noChangeAspect = true;

		CT_BlipFillProperties blipFill = pic.AddNewBlipFill();
		CT_Blip blip = blipFill.AddNewBlip();
		blip.embed = run.Paragraph.Part.GetRelationId(picData);
		blipFill.AddNewStretch().AddNewFillRect();

		CT_ShapeProperties spPr = pic.AddNewSpPr();
		CT_Transform2D xfrm = spPr.AddNewXfrm();

		CT_Point2D off = xfrm.AddNewOff();
		off.x = (0);
		off.y = (0);

		NPOI.OpenXmlFormats.Dml.CT_PositiveSize2D ext = xfrm.AddNewExt();
		ext.cx = 100;
		ext.cy = 100;

		CT_PresetGeometry2D prstGeom = spPr.AddNewPrstGeom();
		prstGeom.prst = (ST_ShapeType.rect);
		prstGeom.AddNewAvLst();

		using (var ms = RecyclableMemory.GetStream())
		{
			StreamWriter sw = new StreamWriter(ms);
			pic.Write(sw, "pic:pic");
			sw.Flush();
			ms.Position = 0;
			var sr = new StreamReader(ms);
			var picXml = sr.ReadToEnd();
			gd.AddPicElement(picXml);
		}

		drawing.anchor.Add(an);
	}

	private XWPFParagraph AddParagraph(XWPFDocument doc)
	{
		XWPFParagraph paragraphy = doc.CreateParagraph();
		CT_PPr ppr = new CT_PPr();
		CT_Spacing sp = ppr.AddNewSpacing();
		// w:spacing w:after="20" w:line="430" w:lineRule="auto" 
		sp.after = 20;
		sp.line = "430";
		sp.lineRule = ST_LineSpacingRule.auto;

		CT_Ind ind = ppr.AddNewInd();
		ind.right = "10";

		CT_Jc jc = ppr.AddNewJc();
		// 左对齐
		jc.val = ST_Jc.left;

		CT_ParaRPr rpr = ppr.AddNewRPr();
		rpr.rFonts = new CT_Fonts();
		rpr.rFonts.ascii = "宋体";
		rpr.rFonts.hAnsi = "宋体";
		rpr.rFonts.eastAsia = "宋体";
		rpr.rFonts.cs = "宋体";
		rpr.b = new CT_OnOff();
		rpr.b.val = true;
		rpr.sz = new CT_HpsMeasure();
		rpr.sz.val = 32;
		paragraphy.GetCTP().pPr = ppr;

		return paragraphy;
	}

	private XWPFParagraph AddTextParagraph(XWPFDocument doc)
	{
		XWPFParagraph paragraphy = doc.CreateParagraph();
		CT_PPr ppr = new CT_PPr();
		CT_Spacing sp = ppr.AddNewSpacing();
		sp.lineRule = ST_LineSpacingRule.auto;
		CT_Ind ind = ppr.AddNewInd();
		CT_Jc jc = ppr.AddNewJc();
		jc.val = ST_Jc.right;

		CT_ParaRPr rpr = ppr.AddNewRPr();
		rpr.rFonts = new CT_Fonts();
		rpr.rFonts.ascii = "宋体";
		rpr.rFonts.hAnsi = "宋体";
		rpr.rFonts.eastAsia = "宋体";
		rpr.rFonts.cs = "宋体";
		rpr.b = new CT_OnOff();
		rpr.b.val = true;
		rpr.sz = new CT_HpsMeasure();
		rpr.sz.val = 32;
		paragraphy.GetCTP().pPr = ppr;

		return paragraphy;
	}

	private XWPFRun AddTextRun(XWPFParagraph paragraphy, string text, ulong fontSize)
	{
		XWPFRun run = paragraphy.CreateRun();
		run.IsBold = true;
		CT_RPr rpr = new CT_RPr();
		CT_Fonts ft = rpr.AddNewRFonts();
		ft.ascii = "宋体";
		ft.hAnsi = "宋体";
		ft.eastAsia = "宋体";
		ft.cs = "宋体";
		rpr.AddNewB();
		CT_HpsMeasure sz = rpr.AddNewSz();
		sz.val = fontSize;
		run.GetCTR().rPr = rpr;
		run.SetText(text);

		return run;
	}

	public bool CreateWordReport(string wordFile)
	{
		try
		{
			string appPath = System.AppDomain.CurrentDomain.BaseDirectory;              
			string checkTime = DateTime.Now.ToString("yyyy年MM月dd日");//检查时间

			//TODO:使用FileStream文件流来写入数据(传入参数为:文件所在路径,对文件的操作方式,对文件内数据的操作)
			//通过使用文件流,创建文件流对象,向文件流中写入内容,并保存为Word文档格式
			using (var stream = new FileStream(wordFile, FileMode.Create, FileAccess.Write))
			{
				//创建document文档对象对象实例
				XWPFDocument doc = new XWPFDocument();

				XWPFParagraph paragraphy = AddParagraph(doc);
				AddBarCode(doc, paragraphy);

				paragraphy = AddTextParagraph(doc);
				AddTextRun(paragraphy, "TEST1", 32);

				paragraphy = AddTextParagraph(doc);
				AddTextRun(paragraphy, "TEST2", 32);

				paragraphy = AddTextParagraph(doc);
				AddTextRun(paragraphy, "TEST3", 32);

				//向文档流中写入内容,生成word
				doc.Write(stream);

				return true;
			}
		}
		catch (Exception ex)
		{
			return false;
		}
	}
}

相关推荐

  1. C# 读去Word文档(NPOI

    2024-05-11 20:32:01       34 阅读
  2. .NET Core NPOI导出Word,浏览器下载

    2024-05-11 20:32:01       28 阅读
  3. .net开发:NPOI生成excel文件到磁盘

    2024-05-11 20:32:01       30 阅读
  4. js生成word

    2024-05-11 20:32:01       37 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-05-11 20:32:01       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-05-11 20:32:01       106 阅读
  3. 在Django里面运行非项目文件

    2024-05-11 20:32:01       87 阅读
  4. Python语言-面向对象

    2024-05-11 20:32:01       96 阅读

热门阅读

  1. LVS(Linux Virtual Server)知识点详解

    2024-05-11 20:32:01       27 阅读
  2. Nginx - location 指令(二)

    2024-05-11 20:32:01       35 阅读
  3. Linux监听某个进程,自动重启

    2024-05-11 20:32:01       32 阅读
  4. 数据字典是什么?

    2024-05-11 20:32:01       35 阅读
  5. 【前端每日基础】day2 const var let的区别

    2024-05-11 20:32:01       36 阅读
  6. MySQL学习笔记12——效率和优化

    2024-05-11 20:32:01       150 阅读
  7. Unity 委托与事件、装箱和拆箱

    2024-05-11 20:32:01       32 阅读
  8. React 学习-5

    2024-05-11 20:32:01       35 阅读
  9. 6.5.Docker数据管理和端口映射应用

    2024-05-11 20:32:01       24 阅读
  10. 算法练习17——罗马数字转整数

    2024-05-11 20:32:01       29 阅读
  11. debian apt 更改阿里源

    2024-05-11 20:32:01       23 阅读
  12. android原生开发学习路线

    2024-05-11 20:32:01       30 阅读