一、引入相关jar
-
<dependency>
-
<groupId>org.apache.poi</groupId>
-
<artifactId>poi-ooxml</artifactId>
-
<version>3.10-FINAL</version>
-
</dependency>
二、原始写法
1)、在首页插入一个表格,单元格中带有图片
-
public static void writeTblWithImageToDocx_1() {
-
BufferedReader in = null;
-
XWPFDocument temp = null;
-
BufferedOutputStream out = null;
-
File tempDoc = new File("d:\\test\\test11.docx");
-
try {
-
//in = new BufferedReader(new InputStreamReader(new FileInputStream("D:\\test\\2.doc"), "ISO8859_1"));
-
temp = new XWPFDocument(new BufferedInputStream(new FileInputStream(tempDoc)));
-
out = new BufferedOutputStream(new FileOutputStream("D:\\test\\test_2.docx"));
-
XWPFParagraph p = temp.getParagraphArray( 0);
-
p.setAlignment(ParagraphAlignment.LEFT);
-
XWPFRun run = p.insertNewRun( 0);
-
-
//表格生成 6行5列.
-
int rows = 6;
-
int cols = 5;
-
XmlCursor cursor = p.getCTP().newCursor();
-
XWPFTable tableOne = temp.insertNewTbl(cursor);
-
-
//样式控制
-
CTTbl ttbl = tableOne.getCTTbl();
-
CTTblPr tblPr = ttbl.getTblPr() == null ? ttbl.addNewTblPr() : ttbl.getTblPr();
-
CTTblWidth tblWidth = tblPr.isSetTblW() ? tblPr.getTblW() : tblPr.addNewTblW();
-
CTJc cTJc = tblPr.addNewJc();
-
cTJc.setVal(STJc.Enum.forString( "center"));//表格居中
-
tblWidth.setW( new BigInteger("9000"));//每个表格宽度
-
tblWidth.setType(STTblWidth.AUTO);
-
-
//表格创建
-
XWPFTableRow tableRowTitle = tableOne.getRow( 0);
-
tableRowTitle.getCell( 0).setText("标题");
-
tableRowTitle.addNewTableCell().setText( "内容");
-
tableRowTitle.addNewTableCell().setText( "姓名");
-
tableRowTitle.addNewTableCell().setText( "日期");
-
tableRowTitle.addNewTableCell().setText( "备注");
-
for (int i = 1; i < rows; i++) {
-
XWPFTableRow createRow = tableOne.createRow();
-
for (int j = 0; j < cols; j++) {
-
createRow.getCell(j).setText( "我是第"+i+"行,第"+(j+1)+"列");
-
}
-
}
-
-
//插入图片测试
-
XWPFTableRow rowTest = tableOne.getRow( 0);
-
-
XWPFTableCell imageCell = rowTest.getCell( 0);
-
List<XWPFParagraph> paragraphs = imageCell.getParagraphs();
-
XWPFParagraph newPara = paragraphs.get( 0);
-
XWPFRun imageCellRunn = newPara.createRun();
-
imageCellRunn.addPicture( new FileInputStream("d:/test/1.png"), XWPFDocument.PICTURE_TYPE_PNG, "1.png", Units.toEMU(600), Units.toEMU(300));
-
run.addBreak();
-
temp.write(out);
-
} catch (UnsupportedEncodingException e) {
-
// TODO 自动生成的 catch 块
-
e.printStackTrace();
-
} catch (FileNotFoundException e) {
-
// TODO 自动生成的 catch 块
-
e.printStackTrace();
-
} catch (IOException e) {
-
// TODO 自动生成的 catch 块
-
e.printStackTrace();
-
} catch (InvalidFormatException i) {
-
// TODO 自动生成的 catch 块
-
i.printStackTrace();
-
}
-
finally {
-
if (in != null) {
-
try {
-
in.close();
-
} catch (IOException e) {
-
// TODO 自动生成的 catch 块
-
e.printStackTrace();
-
}
-
}
-
if (out != null) {
-
try {
-
out.close();
-
} catch (IOException e) {
-
// TODO 自动生成的 catch 块
-
e.printStackTrace();
-
}
-
}
-
// tempDoc.deleteOnExit();
-
}
-
-
System.out.println( "写入完成。。。。。。。。。。。。。。");
-
}
2)、调用该方法
-
public static void main(String[] args) {
-
writeTblWithImageToDocx_1();
-
-
}
3)、结果
WPS:图片是空白的图,无法打开,表格宽度样式无效
Office:无法打开
三、修改代码支持可显示图片
Poi代码bug,亲测3.9和3.10都有该问题,其他版本未测,可自行测试。
修改后代码:
1)、首先重写XWPFDocument,定义构造函数,自定义读取图片的方法
-
public class CustomXWPFDocument extends XWPFDocument {
-
-
public CustomXWPFDocument(InputStream inputStream) throws IOException {
-
super(inputStream);
-
}
-
public void createPic(String blipId, int id, int width, int height, CTInline inline) {
-
final int EMU = 9525;
-
width *= EMU;
-
height *= EMU;
-
//String blipId = getAllPictures().get(id).getPackageRelationship().getId();
-
-
-
//CTInline inline = createParagraph().createRun().getCTR().addNewDrawing().addNewInline();
-
-
-
String picXml = "" +
-
"<a:graphic xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\">" +
-
" <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=\"" + 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>" +
-
" </a:graphicData>" +
-
"</a:graphic>";
-
-
-
//CTGraphicalObjectData graphicData = inline.addNewGraphic().addNewGraphicData();
-
XmlToken xmlToken = null;
-
try {
-
xmlToken = XmlToken.Factory.parse(picXml);
-
} catch (XmlException xe) {
-
xe.printStackTrace();
-
}
-
inline.set(xmlToken);
-
//graphicData.set(xmlToken);
-
-
-
inline.setDistT( 0);
-
inline.setDistB( 0);
-
inline.setDistL( 0);
-
inline.setDistR( 0);
-
-
-
CTPositiveSize2D extent = inline.addNewExtent();
-
extent.setCx(width);
-
extent.setCy(height);
-
-
-
CTNonVisualDrawingProps docPr = inline.addNewDocPr();
-
docPr.setId(id);
-
docPr.setName( "Picture " + id);
-
docPr.setDescr( "Generated");
-
}
-
-
-
}
2)、修改首页插入一个表格,单元格中带有图片的相关代码
-
public static void writeTblWithImageToDocx_2() {
-
BufferedReader in = null;
-
CustomXWPFDocument temp = null;
-
BufferedOutputStream out = null;
-
File tempDoc = new File("d:\\test\\test11.docx");
-
try {
-
//in = new BufferedReader(new InputStreamReader(new FileInputStream("D:\\test\\2.doc"), "ISO8859_1"));
-
temp = new CustomXWPFDocument(new BufferedInputStream(new FileInputStream(tempDoc)));
-
-
out = new BufferedOutputStream(new FileOutputStream("D:\\test\\test_2.docx"));
-
XWPFParagraph p = temp.getParagraphArray( 0);
-
p.setAlignment(ParagraphAlignment.LEFT);
-
XWPFRun run = p.insertNewRun( 0);
-
-
//表格生成 6行5列.
-
int rows = 6;
-
int cols = 5;
-
XmlCursor cursor = p.getCTP().newCursor();
-
XWPFTable tableOne = temp.insertNewTbl(cursor);
-
-
//样式控制
-
CTTbl ttbl = tableOne.getCTTbl();
-
CTTblPr tblPr = ttbl.getTblPr() == null ? ttbl.addNewTblPr() : ttbl.getTblPr();
-
CTTblWidth tblWidth = tblPr.isSetTblW() ? tblPr.getTblW() : tblPr.addNewTblW();
-
CTJc cTJc = tblPr.addNewJc();
-
cTJc.setVal(STJc.Enum.forString( "center"));//表格居中
-
tblWidth.setW( new BigInteger("8000"));//每个表格宽度
-
tblWidth.setType(STTblWidth.DXA);
-
-
//表格创建
-
XWPFTableRow tableRowTitle = tableOne.getRow( 0);
-
tableRowTitle.setHeight( 380);
-
-
tableRowTitle.getCell( 0).setText("标题");
-
tableRowTitle.addNewTableCell().setText( "内容");
-
tableRowTitle.addNewTableCell().setText( "姓名");
-
tableRowTitle.addNewTableCell().setText( "日期");
-
tableRowTitle.addNewTableCell().setText( "备注");
-
for (int i = 1; i < rows; i++) {
-
XWPFTableRow createRow = tableOne.createRow();
-
for (int j = 0; j < cols; j++) {
-
createRow.getCell(j).setText( "我是第"+i+"行,第"+(j+1)+"列");
-
}
-
}
-
-
//插入图片测试
-
XWPFTableRow rowTest = tableOne.getRow( 0);
-
-
XWPFTableCell imageCell = rowTest.getCell( 0);
-
List<XWPFParagraph> paragraphs = imageCell.getParagraphs();
-
XWPFParagraph newPara = paragraphs.get( 0);
-
XWPFRun imageCellRunn = newPara.createRun();
-
String id = temp.addPictureData( new FileInputStream("d:/test/1.png"), XWPFDocument.PICTURE_TYPE_PNG);//添加图片数据
-
-
int id2=temp.getAllPackagePictures().size()+1;
-
-
CTInline ctinline=imageCellRunn.getCTR().addNewDrawing().addNewInline(); //设置段落行
-
temp.createPic(id,id2, 259, 259,ctinline);//添加图片
-
-
mergeCellsHorizontal(tableOne, 0,0,1);//WPS不支持跨列
-
mergeCellsVertically(tableOne, 1,1,2);
-
run.addBreak();
-
temp.write(out);
-
} catch (UnsupportedEncodingException e) {
-
// TODO 自动生成的 catch 块
-
e.printStackTrace();
-
} catch (FileNotFoundException e) {
-
// TODO 自动生成的 catch 块
-
e.printStackTrace();
-
} catch (IOException e) {
-
// TODO 自动生成的 catch 块
-
e.printStackTrace();
-
} catch (InvalidFormatException i) {
-
// TODO 自动生成的 catch 块
-
i.printStackTrace();
-
}
-
finally {
-
if (in != null) {
-
try {
-
in.close();
-
} catch (IOException e) {
-
// TODO 自动生成的 catch 块
-
e.printStackTrace();
-
}
-
}
-
if (out != null) {
-
try {
-
out.close();
-
} catch (IOException e) {
-
// TODO 自动生成的 catch 块
-
e.printStackTrace();
-
}
-
}
-
// tempDoc.deleteOnExit();
-
}
-
-
System.out.println( "写入完成。。。。。。。。。。。。。。");
-
}
3)、新增合并单元格相关代码
-
// word跨列合并单元格
-
public static void mergeCellsHorizontal(XWPFTable table, int row, int fromCell, int toCell) {
-
for (int cellIndex = fromCell; cellIndex <= toCell; cellIndex++) {
-
XWPFTableCell cell = table.getRow(row).getCell(cellIndex);
-
if ( cellIndex == fromCell ) {
-
// The first merged cell is set with RESTART merge value
-
cell.getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.RESTART);
-
} else {
-
// Cells which join (merge) the first one, are set with CONTINUE
-
cell.getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.CONTINUE);
-
}
-
}
-
}
-
// word跨行并单元格
-
public static void mergeCellsVertically(XWPFTable table, int col, int fromRow, int toRow) {
-
for (int rowIndex = fromRow; rowIndex <= toRow; rowIndex++) {
-
XWPFTableCell cell = table.getRow(rowIndex).getCell(col);
-
if ( rowIndex == fromRow ) {
-
// The first merged cell is set with RESTART merge value
-
cell.getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.RESTART);
-
} else {
-
// Cells which join (merge) the first one, are set with CONTINUE
-
cell.getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.CONTINUE);
-
}
-
}
-
}
3)、测试结果
WPS:图片已经正常显示,样式依旧无效,合并列也无效,合并行有效
Office:可以正常显示