Npoi XWPF Word 导出时插入图片无法显示 bug 完美解决

一、来自客户的需求

最近客户来个新需求生成一个word 标签纸,并且需要在标签纸上插入一个logo,并且将erp 中的数据取出来自动写在文档上,不由得淡淡一笑,这不难呀!

于是乎我就写下了这样的代码:

插入文字段落

XWPFParagraph m_xp = doc.CreateParagraph();

LableInfo lable = lableInfos[i];

XWPFRun xwpfRun = m_xp.CreateRun();//创建段落文本对象

xwpfRun.SetTextPosition(-10);

xwpfRun.FontSize = 15;//字体大小

xwpfRun.IsBold = false;//是否加粗

xwpfRun.SetFontFamily(“黑体”, FontCharRange.None);//设置字体(如:微软雅黑,华文楷体,宋体)

xwpfRun.AppendText(“产品名称:”);

插入图片

XWPFParagraph gp = doc.CreateParagraph();

FileStream gfs = new FileStream(@”..\..\logo.png”, FileMode.Open, FileAccess.Read);

gp.SpacingAfterLines = -1;

XWPFRun gr = gp.CreateRun();

gr.AddPicture(gfs, (int)PictureType.PNG, “image1.png”, 2009000, 400000);

gfs.Close();

是不是很轻松就搞定了。

没想到弹出这么个框框,眼前一黑啊!!!!!

二、解决Npio 插入图片报错问题

1、找出问题

用WinRAR打开,对比下正常情况下的数据和报错那个文件的数据有什么不同

找到document.xml 文件,对比下两个文件的差异

错误的文件

正确的文件

2、解决问题

对比发现用代码插入的图片xml 文件和手动操作word插入图片的xml 并非一样,因此我们需要更换下xml就可以解决问题了。

上代码:

 public static void CreatePicture(XWPFRun run, string id, int width , int height )
        {
            try
            {
                int EMU = 9525;
                width *= EMU;
                height *= EMU;
                CT_Inline inline = run.GetCTR().AddNewDrawing().AddNewInline();
                inline.distT = inline.distB = inline.distL = inline.distR = 0;
                inline.graphic = new NPOI.OpenXmlFormats.Dml.CT_GraphicalObject();              

                NPOI.OpenXmlFormats.Dml.CT_GraphicalObjectData graphicData = inline.graphic.AddNewGraphicData();
                graphicData.uri = "http://schemas.openxmlformats.org/drawingml/2006/picture";

                string picXmlstr = "";
                using (StreamReader sr = new StreamReader(@"C:\001.txt", Encoding.UTF8))
                {
                    picXmlstr = sr.ReadToEnd();
                }

                graphicData.AddPicElement(picXmlstr);                

                CT_PositiveSize2D extent = inline.AddNewExtent();

                extent.cx = width;
                extent.cy = height;
                CT_EffectExtent effectExtent = new CT_EffectExtent();
                effectExtent.l =(long)19050;
                effectExtent.t = effectExtent.r = effectExtent.b = 0;
                inline.effectExtent = effectExtent;              
             

                CT_NonVisualDrawingProps docPr = inline.AddNewDocPr();
                docPr.id = 6;
                docPr.name = "图片" + id;
                docPr.descr = "logo.png";

                CT_NonVisualGraphicFrameProperties cT_Non = new CT_NonVisualGraphicFrameProperties();
                NPOI.OpenXmlFormats.Dml.CT_GraphicalObjectFrameLocking cT_Graphical =new NPOI.OpenXmlFormats.Dml.CT_GraphicalObjectFrameLocking();
                cT_Graphical.noChangeAspect = true;
                cT_Non.graphicFrameLocks = cT_Graphical;
                inline.cNvGraphicFramePr = cT_Non;
            }
            catch (Exception ex)
            {

            }
        }


picXmlstr 是一个xml 文件

  
    
    
  
  
    
    
      
    
  
  
    
      
      
    
    
      
    
  

调用代码入下:

XWPFParagraph wPFParagraph = doc.CreateParagraph();
                    FileStream gfs = new FileStream(@"..\..\logo.png", FileMode.Open, FileAccess.Read);
                    var picID = doc.AddPictureData(gfs, (int)PictureType.PNG);
                    gfs.Close();gfs.Dispose();
                    CreatePicture(wPFParagraph.CreateRun(), picID, 2009000, 400000);

3、大功告成