问题描述

在使用poi-tl word模版工具时,发现生成的文档中,图片格式为嵌入型,有的图片甚至被表格遮挡一半。而自己想要的图片格式为上下型环绕,并且图片需要居中。

问题分析

poi-tl渲染图片,使用的是org.apache.poi.xwpf.usermodel.XWPFRun的addPicture方法,该方法中有一段代码:CTInline inline = drawing.addNewInline();意思就是默认将图片转为inline类型,即行内元素。

然后我们把生成的嵌入型图片的文档转换成xml文件,然后再新建一个文档,插入图片后,设置图片为上下型环绕,保存为另一个xml,比较下两个xml的区别。嵌入型图片的xml是:

上下型环绕的图片的xml是

我们看到两种格式的图片标签分别为inline和anchor。所以如果我们想把图片设置为上下型环绕,需要重写poi的addPicture方法,把图片转为anchor类型。

我们仿照org.apache.poi.xwpf.usermodel.XWPFRun的addPicture方法,将CTInline inline = drawing.addNewInline();换成 CTAnchor anchor = drawing.addNewAnchor();,然后对比着xml,依次对anchor的字段进行赋值。结果发现生成的word无法正常打开,查了很多资料,都说poi的CTAnchor有问题,使用后无法正常打开生成的word。

此路不通,那我们就尝试另一种思路,我们不通过CTAnchor来生成anchor标签,而是直接使用xml,将xml赋给poi的drawing。具体的处理方式在后面。

xml标签和图片格式解析

在word中,在图片上右键,选择大小和位置,就可以看到如下界面:

图中的上下型对应的是xml中的标签,不同环绕方式该标签值不一样。如果需要其他格式,可以设置好后,把文档保存为xml,找到对应的标签。

图中的距正文上下左右距离,对应的是中的disT、disB、disL、disR属性。

图中位置一栏,水平对齐方式居中、相对于栏对应的是xml中的center。

垂直-绝对位置0.1cm,下侧段落对应的是xml中的36195。

我们可以根据不同的需要来设置不同的xml。

我使用的xml是

String xml = "

simplePos=\"0\" distR=\"0\" distL=\"0\" distB=\"0\" distT=\"0\" " +

" xmlns:wp=\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\"" +

" xmlns:wp14=\"http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing\"" +

" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" >" +

"" +

"" +

"center" +

"" +

"" +

"0" +

"" +

"" +

"" +

"" +

"" +

"" +

"" +

"" +

"" +

"" +

"" +

"" +

"" +

"" +

"" +

"" +

"" +

"" +

"" +

"" +

"" +

"" +

"" +

"" +

"" +

"" +

"" +

"" +

"" +

"" +

"" +

"" +

"" +

"" +

"0" +

"" +

"" +

"0" +

"" +

"

";

其中width和height是图片的宽度和高度,relationId是图片的id。

解决方案

1,首先定义一个poi-tl的图片渲染器,使得其不再调用poi默认的图片渲染器,而是使用我们自己定义的。

public class MyPictureRenderPolicy extends AbstractRenderPolicy {

@Override

protected boolean validate(PictureRenderData data) {

return (null != data.getData() || null != data.getPath());

}

@Override

public void doRender(RunTemplate runTemplate, PictureRenderData picture, XWPFTemplate template)

throws Exception {

XWPFRun run = runTemplate.getRun();

MyPictureRenderPolicy.Helper.renderPicture(run, picture);

}

@Override

protected void afterRender(RenderContext context) {

clearPlaceholder(context, false);

}

@Override

protected void doRenderException(RunTemplate runTemplate, PictureRenderData data, Exception e) {

logger.info("Render picture " + runTemplate + " error: {}", e.getMessage());

runTemplate.getRun().setText(data.getAltMeta(), 0);

}

public static class Helper {

public static void renderPicture(XWPFRun run, PictureRenderData picture) throws Exception {

int suggestFileType = suggestFileType(picture.getPath());

InputStream ins = null == picture.getData() ? new FileInputStream(picture.getPath())

: new ByteArrayInputStream(picture.getData());

String relationId = run.getDocument().addPictureData(ins, suggestFileType);

long width = Units.toEMU(picture.getWidth());

long height = Units.toEMU(picture.getHeight());

CTDrawing drawing = run.getCTR().addNewDrawing();

String xml = "

" xmlns:wp=\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\"" +

" xmlns:wp14=\"http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing\"" +

" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" >" +

"" +

"" +

"center" +

"" +

"" +

"0" +

"" +

"" +

"" +

"" +

"" +

"" +

"" +

"" +

"" +

"" +

"" +

"" +

"" +

"" +

"" +

"" +

"" +

"" +

"" +

"" +

"" +

"" +

"" +

"" +

"" +

"" +

"" +

"" +

"" +

"" +

"" +

"" +

"" +

"" +

"0" +

"" +

"" +

"0" +

"" +

"

";

drawing.set(XmlToken.Factory.parse(xml, DEFAULT_XML_OPTIONS));

CTPicture pic = getCTPictures(drawing).get(0);

XWPFPicture xwpfPicture = new XWPFPicture(pic, run);

run.getEmbeddedPictures().add(xwpfPicture);

}

public static List getCTPictures(XmlObject o) {

List pictures = new ArrayList<>();

XmlObject[] picts = o.selectPath("declare namespace pic='"

+ CTPicture.type.getName().getNamespaceURI() + "' .//pic:pic");

for (XmlObject pict : picts) {

if (pict instanceof XmlAnyTypeImpl) {

// Pesky XmlBeans bug - see Bugzilla #49934

try {

pict = CTPicture.Factory.parse(pict.toString(),

DEFAULT_XML_OPTIONS);

} catch (XmlException e) {

throw new POIXMLException(e);

}

}

if (pict instanceof CTPicture) {

pictures.add((CTPicture) pict);

}

}

return pictures;

}

public static int suggestFileType(String imgFile) {

int format = 0;

if (imgFile.endsWith(".emf")) {

format = XWPFDocument.PICTURE_TYPE_EMF;

} else if (imgFile.endsWith(".wmf")) {

format = XWPFDocument.PICTURE_TYPE_WMF;

} else if (imgFile.endsWith(".pict")) {

format = XWPFDocument.PICTURE_TYPE_PICT;

} else if (imgFile.endsWith(".jpeg") || imgFile.endsWith(".jpg")) {

format = XWPFDocument.PICTURE_TYPE_JPEG;

} else if (imgFile.endsWith(".png")) {

format = XWPFDocument.PICTURE_TYPE_PNG;

} else if (imgFile.endsWith(".dib")) {

format = XWPFDocument.PICTURE_TYPE_DIB;

} else if (imgFile.endsWith(".gif")) {

format = XWPFDocument.PICTURE_TYPE_GIF;

} else if (imgFile.endsWith(".tiff")) {

format = XWPFDocument.PICTURE_TYPE_TIFF;

} else if (imgFile.endsWith(".eps")) {

format = XWPFDocument.PICTURE_TYPE_EPS;

} else if (imgFile.endsWith(".bmp")) {

format = XWPFDocument.PICTURE_TYPE_BMP;

} else if (imgFile.endsWith(".wpg")) {

format = XWPFDocument.PICTURE_TYPE_WPG;

} else {

throw new RenderException(

"Unsupported picture: " + imgFile + ". Expected emf|wmf|pict|jpeg|png|dib|gif|tiff|eps|bmp|wpg");

}

return format;

}

}

}

然后在渲染模板的时候,配置我们自己定义的图片渲染器

public static void main(String[] args) throws Exception{

String path = "1.docx";

InputStream templateFile = Demo.class.getClassLoader().getResourceAsStream(path);

Map map = new HashMap();

map.put("pic", new PictureRenderData(120, 80, ".png", Demo.class.getClassLoader().getResourceAsStream("1.png")));

// 将数据整合到模板中去

Configure.ConfigureBuilder builder = Configure.newBuilder();

builder.supportGrammerRegexForAll();

builder.addPlugin('@', new MyPictureRenderPolicy());

XWPFTemplate template = XWPFTemplate.compile(templateFile, builder.build()).render(map);

String docPath = "C:\\Users\\csdc01\\Desktop\\out.docx";

FileOutputStream outputStream1 = new FileOutputStream(docPath);

template.write(outputStream1);

outputStream1.flush();

outputStream1.close();

}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

poi 拆分带图片的word_java poi设置生成的word的图片为上下型环绕以及其位置的实现...相关推荐

  1. xwpftemplate的时间设置_java poi设置生成的word的图片为上下型环绕以及其位置

    问题描述 在使用poi-tl word模版工具时,发现生成的文档中,图片格式为嵌入型,有的图片甚至被表格遮挡一半.而自己想要的图片格式为上下型环绕,并且图片需要居中. 问题分析 poi-tl渲染图片, ...

  2. java图片位置设置_java poi设置生成的word的图片为上下型环绕以及其位置

    问题描述 在使用poi-tl word模版工具时,发现生成的文档中,图片格式为嵌入型,有的图片甚至被表格遮挡一半.而自己想要的图片格式为上下型环绕,并且图片需要居中. 问题分析 poi-tl渲染图片, ...

  3. python 验证码图片 模拟登录_Python 模拟生成动态产生验证码图片的方法

    模拟动态产生验证码图片 模拟生成验证码,首先要做的是生成随机的字母,然后对字母进行模糊处理.这里介绍一下 Python 提供的 Pillow 模块. Pillow PIL:Python Image L ...

  4. poi 拆分带图片的word_学会这2招,再多的“表格编号”都能轻松解决!【Word教程】...

    点击图片   1元抢购 Excel.Word.PPT全套课程 最近有位朋友向我抱怨说,在Word编辑表格时,添加编号实在是太麻烦,不像excel表格Excel那样能够自动填充.都是手动输入来搞定,容易 ...

  5. html图片占位符怎么设置,使用CSS3 Gradients创建图片占位符

    最典型的问题是在画册制作中,没有显示出足够多图片: 解决方案有很多种,你可以在后面直接留空白区域:你也可以添加额外的html标签作为占位符.第一种方案觉得还可以,但第二种解决方案感觉会让你的代码不干净 ...

  6. python生成海报商品图片_如何优雅的生成海报/动态合成图片 ?

    poster-generater ⚡⚡⚡海报生成器. 只需要一个简单的 json 配置即可生成你需要的海报... 说明 此项目诞生有一段时间了,我本人也一直在使用这个程序,从一开始的 golang 版 ...

  7. php 图片抠图,php 图像处理 抠图,生成背景透明png 图片

    *自定义一个图片等比缩放函数 *@param string $picname 被缩放图片名 *@param string $path 被缩放图片路径 *@param int $maxWidth 图片被 ...

  8. 图片适应窗口_毕业论文排版保姆级教程——图片和公式排版

    [小技巧]Origin作图过程中如何让图看起来更生动 2020-05-30 [小技巧]简单设置让你origin导出的图片不在有大白边 2020-05-29 [干货放送]萤火科研资源免费赠送第一期--必 ...

  9. 生成具有三态背景图片的按钮

    生成具有三态背景图片的按钮 class PussButton:## 生成具有三态背景图片的按钮#def init(self, *imgPath):from PyQt5.QtWidgets import ...

最新文章

  1. 使用NuGet下载旧版本的软件包
  2. NTFRS事件ID:13568
  3. 8. python list 和 tuple
  4. linux系统调用理解之摘录(1)
  5. 再见,汉斯·罗斯林,你用数据让宏大的问题变有趣 | 好奇心小数据
  6. matlab语法手册下载,MATLAB及其在理工课程中的应用指南 第4版.pdf
  7. Android之在linux终端执行shell脚本文件(通过aapt)得到apk包名
  8. linux 向程序发送信号,Linux下的信号处理
  9. 微信 获取wx.config 参数 基类
  10. linux修改key文件夹,linux 中如何根据xml文件的key来修改value呢?
  11. azure vnc控制台_使用扩展和标签控制Azure成本
  12. 《设计模式沉思录》—第2章2.4节访问权限
  13. Qt 萤石云 /萤石云官方Demo二次开发 Qt 5.12.3 / H5/萤石云官方Demo
  14. Win11 22527.201更新补丁包下载
  15. itext pdf合并
  16. 九歌计算机在线作诗硬件原理,清华大学矣晓沅:「九歌」——基于深度学习的中国古典诗歌自动生成系统...
  17. json转xml报[java.lang.NoClassDefFoundError: nu/xom/Serializer]
  18. 仿写携程旅游手机浏览器页面
  19. Android之如何分析手机系统相册图片和视频删除后保存的位置
  20. CAD标注常见问题:为什么CAD软件快速标注后中间有很多0?

热门文章

  1. 离开网易的转型之路3:热爱测试之路-路上的风景
  2. linux视频教程之dhcp
  3. php中this,self,parent三个关键字之间的区别(转载)
  4. Free_NAS 0.72 安装中
  5. Silverlight 数据显示和布局控件 示例
  6. feng作品推荐あかね色に染まる坂 染成茜色的坂道 (含下载、攻略)
  7. 在服务器托管中对流量和带宽进行限制
  8. 如何保护企业网络免受DDoS攻击?—Vecloud微云
  9. 洛谷 P4175: bzoj 1146: [CTSC2008]网络管理
  10. Leetcode 295. 数据流的中位数