1.首先定位到自定义变量名
2.然后先清除自定义变量名,可利用setText(null,0)来清除
3.在自定义变量名的位置添加图片,使用下面的代码
4.对于图片布局有要求的,利用CTAnchor进行实现
addNewWrapNone;//根据setBehindDoc,来确定浮于文字上方还是下方
addNewWrapSquare;//四周型布局
【注:默认是嵌入型,文字会遮挡部分图片。】
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>5.2.5</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>5.2.5</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-scratchpad</artifactId>
<version>5.2.5</version>
</dependency>
public static void main(String[] args) throws Exception {
String wenshuUrl = "D:\\demo1.docx";
File file = new File(wenshuUrl);
byte[] bytes = Files.readAllBytes(Paths.get(file.toURI()));
ByteArrayInputStream in = new ByteArrayInputStream(bytes);
XWPFDocument doc = new XWPFDocument(in);
String pic = "D:\\demo1.png";
File file2 = new File(pic);
byte[] bytes2 = Files.readAllBytes(Paths.get(file2.toURI()));
ByteArrayInputStream bis2 = new ByteArrayInputStream(bytes2);
for (int i = 0; i < doc.getTables().size(); i++) {
for (int rowIndex = 0; rowIndex < doc.getTables().get(i).getRows().size(); rowIndex++) {
XWPFTableRow row = doc.getTables().get(i).getRow(rowIndex);
row.getTableCells().stream().forEach(cell -> {
for (XWPFParagraph paragraph : cell.getParagraphs()) {
List<XWPFRun> runs = paragraph.getRuns();
for (XWPFRun run : runs) {
try {
addPicture(run, bis2,pic,500,400);
} catch (InvalidFormatException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
} catch (SAXException e) {
throw new RuntimeException(e);
} catch (XmlException e) {
throw new RuntimeException(e);
}
}
}
});
}
}
OutputStream output = new FileOutputStream("D:\\afteradd1.doc");
doc.write(output);
output.close();
}
/**
* 添加图片(布局环绕模式)
* @param run
* @param stream 图片流
* @param filename 文件路径
* @param width 图片的宽度
* @param height 图片的高度
*/
private static void addPicture(XWPFRun run, InputStream stream, String filename, int width, int height ) throws InvalidFormatException, IOException, SAXException, XmlException {
run.addPicture(stream, getPictureTypeByFileName(filename), filename, Units.toEMU(width), Units.toEMU(height));
CTDrawing drawing = run.getCTR().getDrawingArray(0);
CTGraphicalObject graphicalObject = drawing.getInlineArray(0).getGraphic();
//这个是relationId,即图片位置的id
long id = drawing.getInlineArray(0).getDocPr().getId();
//设置一个浮动模式
CTAnchor anchor = drawing.addNewAnchor();
//创建一个包含浮动模式的xml字符串
String xml = "<a:graphic xmlns:a=\"" + CTGraphicalObject.type.getName().getNamespaceURI() + "\"><a:graphicData uri=\"" + CTPicture.type.getName().getNamespaceURI() + "\"><pic:pic xmlns:pic=\"" + CTPicture.type.getName().getNamespaceURI() + "\" /></a:graphicData></a:graphic>";
//将xml字符串转换为InputSource对象
InputSource is = new InputSource(new StringReader(xml));
//生成Document对象,用于将
Document doc = DocumentHelper.readDocument(is);
anchor.set(XmlToken.Factory.parse(doc.getDocumentElement(),DEFAULT_XML_OPTIONS));
//设置浮动位置,0表示紧贴文字
anchor.setDistT(0L);
anchor.setDistR(0L);
anchor.setDistB(0L);
anchor.setDistL(0L);
anchor.setLocked(false);
anchor.setLayoutInCell(true);
anchor.setSimplePos2(false);
anchor.setAllowOverlap(true);
anchor.setRelativeHeight(0);
//图片的布局环绕模式
anchor.addNewWrapSquare();
CTPosH ctPosH = anchor.addNewPositionH();
//STRelFromH 水平方向的位置相对于谁进行调整 character:文字
ctPosH.setRelativeFrom(STRelFromH.CHARACTER);
//调整水平方向的位置,从左往右递增,0代表紧贴文字
ctPosH.setPosOffset( Units.toEMU(0));
CTPosV ctPosV = anchor.addNewPositionV();
//STRelFromV 垂直方向的位置相对于谁进行调整 PARAGRAPH:字段
ctPosV.setRelativeFrom(STRelFromV.PARAGRAPH);
//调整垂直方向的位置,从上往下数值递增
ctPosV.setPosOffset( Units.toEMU(-10));
CTPoint2D ctPoint2D = anchor.addNewSimplePos();
ctPoint2D.setX(0);
ctPoint2D.setY(0);
anchor.addNewCNvGraphicFramePr();
CTNonVisualDrawingProps docPr = anchor.addNewDocPr();
docPr.setId(id);
docPr.setName("Drawing " + id);
docPr.setDescr(filename);
CTPositiveSize2D extent = anchor.addNewExtent();
extent.setCx(Units.toEMU(width));
extent.setCy(Units.toEMU(height));
anchor.setGraphic(graphicalObject);
//添加浮动属性
drawing.setAnchorArray(new CTAnchor[]{anchor});
//删除行内属性
drawing.removeInline(0);
}
public static int getPictureTypeByFileName(String fileName) {
if (StringUtils.isEmpty(fileName)) {
throw new RuntimeException("文件名称不能为空!");
}
String suffix = fileName.substring(fileName.lastIndexOf("."));
switch (suffix) {
case ".jpg":
case ".jpeg":
return XWPFDocument.PICTURE_TYPE_JPEG;
case ".wmf":
return XWPFDocument.PICTURE_TYPE_WMF;
case ".png":
case ".PNG":
return XWPFDocument.PICTURE_TYPE_PNG;
case ".gif":
return XWPFDocument.PICTURE_TYPE_GIF;
case ".tiff":
return XWPFDocument.PICTURE_TYPE_TIFF;
case ".bmp":
return XWPFDocument.PICTURE_TYPE_BMP;
default:
throw new RuntimeException("不支持的文件类型:" + suffix);
}
}