1. 程式人生 > 實用技巧 >Npoi XWPF Word 匯出時插入圖片無法顯示 bug 完美解決

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 檔案
<pic:pic xmlns:pic="http://schemas.openxmlformats.org/drawingml/2006/picture">
  <pic:nvPicPr>
    <pic:cNvPr id="0" name="logo.png" />
    <pic:cNvPicPr />
  </pic:nvPicPr>
  <pic:blipFill>
    <a:blip r:embed="rId4" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" />
    <a:stretch xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main">
      <a:fillRect />
    </a:stretch>
  </pic:blipFill>
  <pic:spPr>
    <a:xfrm xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main">
      <a:off x="0" y="0" />
      <a:ext cx="1505160" cy="476317" />
    </a:xfrm>
    <a:prstGeom prst="rect" xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main">
      <a:avLst />
    </a:prstGeom>
  </pic:spPr>
</pic:pic>

呼叫程式碼入下:

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、大功告成