org.apache.poi
poi-ooxml
3.10-FINAL
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 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 = "" +
"" +
" " +
" " +
" " +
" " +
" " +
" " +
" " +
" " +
" " +
" " +
" " +
" " +
" " +
" " +
" " +
" " +
" " +
" " +
" " +
" " +
" " +
" " +
" " +
" ";
//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 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:可以正常显示