使用 DocumentFormat.OpenXml 将word中的模板字符替换为图片

这个功能用NPOI来做会跟简单一点,NPOI XWPFRun类下有一个AddPicture API 可以直接调用API来替换,我这边因为是做了一个onlyOffice在线编辑的功能,onlyOffice编辑过的文档格式与NPOI兼容,所以找到了这个。

  1. 安装包

Install-Package DocumentFormat.OpenXml

2、来一个配置模型

using DocumentFormat.OpenXml.Packaging;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;

namespace ReportGeneration.Model
{
    public class ImageData_Model
    {
        public string FileName = string.Empty;
        public byte[] BinaryData;
        public Stream DataStream => new MemoryStream(BinaryData);
        public ImagePartType ImageType
        {
            get
            {
                var ext = Path.GetExtension(FileName).TrimStart('.').ToLower();
                switch (ext)
                {
                    case "jpg":
                        return ImagePartType.Jpeg;
                    case "png":
                        return ImagePartType.Png;
                    case "":
                        return ImagePartType.Gif;
                    case "bmp":
                        return ImagePartType.Bmp;
                }
                throw new ApplicationException($"Unsupported image type: {ext}");
            }
        }
        public int SourceWidth;
        public int SourceHeight;
        public decimal Width;
        public decimal Height;
        public long WidthInEMU => Convert.ToInt64(Width * CM_TO_EMU);
        public long HeightInEMU => Convert.ToInt64(Height * CM_TO_EMU);
        private const decimal INCH_TO_CM = 2.54M;
        private const decimal CM_TO_EMU = 360000M;
        public string ImageName;
        public ImageData_Model(string fileName, byte[] data, int dpi = 300)
        {
            FileName = fileName;
            BinaryData = data;
            //Bitmap img = new Bitmap(new MemoryStream(data));
            SourceWidth = 1;
            SourceHeight = 1;
            Width = ((decimal)SourceWidth) / dpi * INCH_TO_CM;
            Height = ((decimal)SourceHeight) / dpi * INCH_TO_CM;
            ImageName = $"IMG_{Guid.NewGuid().ToString().Substring(0, 8)}";
        }
        public ImageData_Model(string fileName, int dpi = 300) :
            this(fileName, File.ReadAllBytes(fileName), dpi)

        {
        }
    }
}
  1. 替换帮助类

注意:命名空间的引用,部分命名空间下有相同的属性注意区分

using System.IO;
using System.Linq;
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;
using ReportGeneration.Model;
using A = DocumentFormat.OpenXml.Drawing;
using DW = DocumentFormat.OpenXml.Drawing.Wordprocessing;
using PIC = DocumentFormat.OpenXml.Drawing.Pictures;
namespace ReportGeneration.Helper
{
    /// <summary>
    /// 使用DocumentFormat.OpenXml替换word中模板字符串为图片
    /// </summary>
    public class DocxImgHelper
    {

        /// <summary>
        /// 替换word中占位符为图片
        /// </summary>
        /// <param name="document">word实例</param>
        /// <param name="imagePath">图片绝对地址</param>
        /// <param name="placeholder">占位符</param>
        public static void DocxImageReplace(WordprocessingDocument document,string imagePath,string placeholder)
        {

            var cat1Img = new ImageData_Model(imagePath)
                {
                    Width = 15,
                    Height = 9
            };
                //var cat2Img = new ImageData(imagePaths);
                var imgRun = GenerateImageRun(document, cat1Img);
                var runCAT = document.MainDocumentPart.Document.Body.Descendants()
            .Single(o => o.LocalName == "r" && o.InnerText == placeholder);
            //document.MainDocumentPart.Document.Body.AppendChild(new Paragraph(imgRun));
            //將 InnerXML 替换成图片 Run 的 InnerXML
            runCAT.InnerXml = imgRun.InnerXml;
        }

        /// <summary>
        /// 生成图像
        /// </summary>
        /// <param name="wordDoc"></param>
        /// <param name="img"></param>
        /// <returns></returns>
        private static Run GenerateImageRun(WordprocessingDocument wordDoc, ImageData_Model img)
        {
            MainDocumentPart mainPart = wordDoc.MainDocumentPart;

            ImagePart imagePart = mainPart.AddImagePart(ImagePartType.Jpeg);
            var relationshipId = mainPart.GetIdOfPart(imagePart);
            imagePart.FeedData(img.DataStream);

            // Define the reference of the image.
            var element =
                 new Drawing(
                     new DW.Inline(
                         //Size of image, unit = EMU(English Metric Unit)
                         //1 cm = 360000 EMUs
                         new DW.Extent() { Cx = img.WidthInEMU, Cy = img.HeightInEMU },
                         new DW.EffectExtent()
                         {
                             LeftEdge = 0L,
                             TopEdge = 0L,
                             RightEdge = 0L,
                             BottomEdge = 0L
                         },
                         new DW.DocProperties()
                         {
                             Id = (UInt32Value)1U,
                             Name = img.ImageName
                         },
                         new DW.NonVisualGraphicFrameDrawingProperties(
                             new A.GraphicFrameLocks() { NoChangeAspect = true }),
                         new A.Graphic(
                             new A.GraphicData(
                                 new PIC.Picture(
                                     new PIC.NonVisualPictureProperties(
                                         new PIC.NonVisualDrawingProperties()
                                         {
                                             Id = (UInt32Value)0U,
                                             Name = img.FileName
                                         },
                                         new PIC.NonVisualPictureDrawingProperties()),
                                     new PIC.BlipFill(
                                         new A.Blip(
                                             new A.BlipExtensionList(
                                                 new A.BlipExtension()
                                                 {
                                                     Uri =
                                                        "{28A0092B-C50C-407E-A947-70E740481C1C}"
                                                 })
                                         )
                                         {
                                             Embed = relationshipId,
                                             CompressionState =
                                             A.BlipCompressionValues.Print
                                         },
                                         new A.Stretch(
                                             new A.FillRectangle())),
                                     new PIC.ShapeProperties(
                                         new A.Transform2D(
                                             new A.Offset() { X = 0L, Y = 0L },
                                             new A.Extents()
                                             {
                                                 Cx = img.WidthInEMU,
                                                 Cy = img.HeightInEMU
                                             }),
                                         new A.PresetGeometry(
                                             new A.AdjustValueList()
                                         )
                                         { Preset = A.ShapeTypeValues.Rectangle }))
                             )
                             { Uri = "http://schemas.openxmlformats.org/drawingml/2006/picture" })
                     )
                     {
                         DistanceFromTop = (UInt32Value)0U,
                         DistanceFromBottom = (UInt32Value)0U,
                         DistanceFromLeft = (UInt32Value)0U,
                         DistanceFromRight = (UInt32Value)0U,
                         EditId = "50D07946"
                     });
            return new Run(element);
        }
    }
}
  1. 调用

//图表
//参数注解在帮助类注释上有
 DocxImgHelper.DocxImageReplace(document, $"{ImagePath}/{flagConfig.Value}",itemInnerText);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值