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
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值