开启辅助访问
 找回密码
 注册帐号

扫一扫,访问微社区

开发者专栏

关注:1907

当前位置:游戏蛮牛 技术专区 开发者专栏

__________________________________________________________________________________
开发者干货区版块规则:

  1、文章必须是图文形式。(至少2幅图)
      2、文章字数必须保持在1500字节以上。(编辑器右下角有字数检查)
      3、本版块只支持在游戏蛮牛原创首发,不支持转载。
      4、本版块回复不得无意义,如:顶、呵呵、不错......【真的会扣分的哦】
      5、......
__________________________________________________________________________________
查看: 407|回复: 7

[小贱] NPOI导出Word无法插入图片

[复制链接]  [移动端链接]
排名
945
昨日变化
1

13

主题

141

帖子

2251

积分

Rank: 9Rank: 9Rank: 9

UID
14099
好友
23
蛮牛币
2986
威望
0
注册时间
2014-2-11
在线时间
589 小时
最后登录
2017-10-19

七夕浪漫情人专栏作家

QQ
发表于 2017-10-11 18:51:02 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?注册帐号

x
本帖最后由 佑丶小贱 于 2017-10-11 18:51 编辑

很多时候,我们需要在没有安装OFFICE的电脑上也能读写Word、Excel,在.Net环境下,我们会使用NPOI插件来实现。
NPOI 是 POI 项目的 .NET 版本。POI是一个开源的Java读写Excel、WORD等微软OLE2组件文档的项目我们需要实现的目标就是读模板->写入数据->生成word。但是有个很普遍的问题,使用NPOI在Word中插入图片的时候出现了无法打开文件,因为内容有错误或者就是打开后不显示图片


google了一下,有遇到过相同问题的,大致分析问题是出在document.xml中的格式中。如何查看document.xml?

1.jpg 2.jpg

这是一个只添加了标题的文档


3.jpg

4.jpg 5.jpg

这是在上面的文档中使用NPOI的 6.jpg 插入了一张图片,可是出现了错误,导致文档无法打开


分析前后文档的xml,插入图片后,到底添加了什么呢?
[XML] 纯文本查看 复制代码
<?xml version="1.0" encoding="utf-8"?>
<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:ve="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml" xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main">
  <w:body>
    <w:p w:rsidR="009F1D27" w:rsidRDefault="00892110" w:rsidP="006D677D">
      <w:pPr>
        <w:pStyle w:val="1"/>
      </w:pPr>
      <w:r>
        <w:rPr>
          <w:rFonts w:hint="eastAsia"/>
        </w:rPr>
        <w:t xml:space="preserve">测试</w:t>
      </w:r>
    </w:p>
    <w:p w:rsidR="006D677D" w:rsidRPr="006D677D" w:rsidRDefault="002A5658" w:rsidP="008C112B">
      <w:pPr/>
      <w:r>
        <w:t xml:space="preserve"/>
        <w:drawing>
          <wp:inline distT="0" distB="0" distL="0" distR="0">
            <wp:extent cx="4762500" cy="3810000"/>
            <wp:effectExtent l="0" t="0" r="0" b="0"/>
            <wp:docPr id="2" name="Picture 2.jpg" descr="Generated"/>
            <wp:cNvGraphicFramePr>
              <a:graphicFrameLocks noChangeAspect="1"/>
            </wp:cNvGraphicFramePr>
            <a:graphic>
              <a:graphicData uri="http://schemas.openxmlformats.org/drawingml/2006/picture">
                <pic:pic xmlns:pic="http://schemas.openxmlformats.org/drawingml/2006/picture">
                  <pic:nvPicPr>
                    <pic:cNvPr id="2" name="Generated"/>
                    <pic:cNvPicPr/>
                  </pic:nvPicPr>
                  <pic:blipFill>
                    <a:blip r:embed="rId6"></a:blip>
                    <a:stretch>
                      <a:fillRect/>
                    </a:stretch>
                  </pic:blipFill>
                  <pic:spPr>
                    <a:xfrm>
                      <a:off x="0" y="0"/>
                      <a:ext cx="4762500" cy="3810000"/>
                    </a:xfrm>
                    <a:prstGeom prst="rect">
                      <a:avLst/>
                    </a:prstGeom>
                  </pic:spPr>
                </pic:pic>
              </a:graphicData>
            </a:graphic>
          </wp:inline>
        </w:drawing>
      </w:r>
      <w:bookmarkStart w:id="0" w:name="_GoBack"/>
      <w:bookmarkEnd w:id="0"/>
    </w:p>
    <w:sectPr w:rsidR="006D677D" w:rsidRPr="006D677D" w:rsidSect="009A6015">
      <w:pgSz w:w="11906" w:h="16838"/>
      <w:pgMar w:top="1440" w:right="1800" w:bottom="1440" w:left="1800" w:header="851" w:footer="992"/>
      <w:cols w:space="425"/>
      <w:docGrid w:type="lines" w:linePitch="312"/>
    </w:sectPr>
  </w:body>

</w:document>

既然之前有人提到了问题出在NPOI未将图片的XML段正确地插入到XML文档中,那我们是不是能给他补上是不是就能解决整个问题了?我用下面的代码来重新添加正确的XML
[C#] 纯文本查看 复制代码
using System;
using NPOI.XWPF.UserModel;
using NPOI.OpenXmlFormats.Dml.WordProcessing;
using System.Xml;
using System.Xml.Serialization;
using System.IO;

namespace Json2Word
{
    public class MyXWPFDocument : XWPFDocument // 重写[/size][size=3]XWPFDocument 类,添加[/size][size=3]AddPicture方法来添加图片[/size][size=3]
    {
        public MyXWPFDocument(Stream stream) : base(stream)
        {

        }

        public void AddPicture(XWPFRun r, String blipId, int id, int width, int height)
        {
            const int EMU = 9525;
            width *= EMU;
            height *= EMU;

            CT_Inline inline = r.GetCTR().AddNewDrawing().AddNewInline();
            String picXml = "" +
                "<pic:pic xmlns:pic=\"http://schemas.openxmlformats.org/drawingml/2006/picture\">" +
                "<pic:nvPicPr>" +
                "<pic:cNvPr id=\"" + id + "\" name=\"Generated\"/>" +
                "<pic:cNvPicPr/>" +
                "</pic:nvPicPr>" +
                "<pic:blipFill>" +
                "<a:blip r:embed=\"" + blipId + "\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"/>" +
                "<a:stretch>" +
                "<a:fillRect/>" +
                "</a:stretch>" +
                "</pic:blipFill>" +
                "<pic:spPr>" +
                "<a:xfrm>" +
                "<a:off x=\"0\" y=\"0\"/>" +
                "<a:ext cx=\"" + width + "\" cy=\"" + height + "\"/>" +
                "</a:xfrm>" +
                "<a:prstGeom prst=\"rect\">" +
                "<a:avLst/>" +
                "</a:prstGeom>" +
                "</pic:spPr>" +
                "</pic:pic>";
            inline.graphic = new NPOI.OpenXmlFormats.Dml.CT_GraphicalObject();
            NPOI.OpenXmlFormats.Dml.CT_GraphicalObjectData graphicalObjectData = inline.graphic.AddNewGraphicData();
            graphicalObjectData.uri = "http://schemas.openxmlformats.org/drawingml/2006/picture";
            graphicalObjectData.AddPicElement(picXml);

            CT_NonVisualDrawingProps docPr = inline.AddNewDocPr();
            docPr.id = (uint)id;
            docPr.name = "Picture " + id + ".jpg";
            docPr.descr = "Generated";

            CT_PositiveSize2D extent = inline.AddNewExtent();
            extent.cx = width;
            extent.cy = height;

            inline.cNvGraphicFramePr = new CT_NonVisualGraphicFrameProperties();
            inline.cNvGraphicFramePr.graphicFrameLocks = new NPOI.OpenXmlFormats.Dml.CT_GraphicalObjectFrameLocking();
            inline.cNvGraphicFramePr.graphicFrameLocks.noChangeAspect = true;

            inline.effectExtent = new CT_EffectExtent();
            inline.effectExtent.l = 0;
            inline.effectExtent.t = 0;
            inline.effectExtent.r = 0;
            inline.effectExtent.b = 0;

            inline.distB = 0;
            inline.distL = 0;
            inline.distR = 0;
            inline.distT = 0;
        }

代码中的
picXml 是我们手动添加的图片部分,同样可以举一反三,添加自己需要的组件类型。在应用场景中,我们使用如下方法调用:
[C#] 纯文本查看 复制代码
using (FileStream fs = File.OpenRead(Application.StartupPath + child.PicPath))[/size][size=3]{
        byte[] bytes = new byte[fs.Length];
        fs.Read(bytes, 0, (int)fs.Length);
        String picId = doc.AddPictureData(bytes, (int)PictureType.JPEG);
        // 将图片添加到段落中
        p = doc.Paragraphs[child.Index]; // [/size][size=3]Index为段落序号[/size][size=3]
        XWPFRun r = p.Runs[child.Run]; // Run为段落中的单位序号
        r.SetText("");
        doc.AddPicture(r, picId, doc.GetNextPicNameNumber((int)PictureType.JPEG), child.Width, child.Hight); // 用图片替换掉Run中的内容[/size]
[size=3]}

现在使用NPOI来添加图片是不是很简单?注意:无法添加图片的错误一般出现在读取模板后修改内容时,新建Word时插入图片不会报错。

另外,我想请教一下InsertNewParagraph的问题,如果有对NPOI比较了解的大佬请私信指导一下!

点评

不错  发表于 2017-10-12 15:45

评分

参与人数 1鲜花 +2 收起 理由
小宅宅 + 2 很给力!

查看全部评分


回复

使用道具 举报

7日久生情
1928/5000
排名
6380
昨日变化
1

4

主题

1579

帖子

1928

积分

Rank: 7Rank: 7Rank: 7Rank: 7

UID
209186
好友
2
蛮牛币
2535
威望
0
注册时间
2017-3-1
在线时间
189 小时
最后登录
2017-10-20
发表于 2017-10-12 09:08:09 | 显示全部楼层
学习了,谢分享

回复

使用道具 举报

8常驻蛮牛
5701/10000
排名
245
昨日变化

0

主题

2831

帖子

5701

积分

Rank: 8Rank: 8

UID
3215
好友
0
蛮牛币
305
威望
0
注册时间
2013-9-4
在线时间
1286 小时
最后登录
2017-10-21
发表于 2017-10-12 09:18:06 | 显示全部楼层
dddddddddddddddd

回复 支持 反对

使用道具 举报

7日久生情
1907/5000
排名
711
昨日变化

1

主题

246

帖子

1907

积分

Rank: 7Rank: 7Rank: 7Rank: 7

UID
27816
好友
3
蛮牛币
5864
威望
0
注册时间
2014-6-3
在线时间
600 小时
最后登录
2017-10-20
发表于 2017-10-12 09:57:42 | 显示全部楼层
表示用wps的路过

回复 支持 反对

使用道具 举报

7日久生情
3768/5000
排名
86
昨日变化

0

主题

736

帖子

3768

积分

Rank: 7Rank: 7Rank: 7Rank: 7

UID
13925
好友
0
蛮牛币
21
威望
0
注册时间
2014-2-9
在线时间
944 小时
最后登录
2017-10-22
发表于 2017-10-12 22:36:46 | 显示全部楼层
学习学习!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
[发帖际遇]: zgledu 乐于助人,奖励 3 蛮牛币. 幸运榜 / 衰神榜

回复

使用道具 举报

3偶尔光临
210/300
排名
7774
昨日变化
76

0

主题

45

帖子

210

积分

Rank: 3Rank: 3Rank: 3

UID
239467
好友
0
蛮牛币
539
威望
0
注册时间
2017-8-24
在线时间
49 小时
最后登录
2017-10-22
发表于 2017-10-13 08:54:04 | 显示全部楼层

学习了,谢分享

回复

使用道具 举报

4四处流浪
346/500
排名
7609
昨日变化
80

3

主题

167

帖子

346

积分

Rank: 4

UID
234982
好友
0
蛮牛币
670
威望
0
注册时间
2017-7-30
在线时间
64 小时
最后登录
2017-10-22
发表于 2017-10-13 09:20:30 | 显示全部楼层
{:87:}{:87:}{:87:}{:87:}{:87:}{:87:}{:87:}{:87:}{:87:}{:87:}{:87:}{:87:}{:87:}{:87:}{:87:}{:87:}{:87:}{:87:}{:87:}

回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册帐号

本版积分规则

快速回复 返回顶部 返回列表