poi版本:4.1.2
最近word导出时需要导出图片,在网上翻了会就发现了好心人分享的代码,但是只支持本地文件读取,我们项目需要从其他服务器获取图片,那肯定得使用网络方式了,于是在源代码上进行了完善,可接收本地和网络两种url方式。
完善后的代码如下:
/**
* 批量插入多张图片,一张一行
* @param cell word表格的某单元格
* @param urlList 支持本地文件和网络文件
* @throws Exception
*/
public void setCellImg(XWPFTableCell cell, List<String> urlList) {
try{
//获取单元格的段落
XWPFParagraph paragraphs = cell.getParagraphs().get(0);
XWPFRun run = paragraphs.getRuns().isEmpty() ? paragraphs.createRun() : paragraphs.getRuns().get(0);
int index=0;
ByteArrayOutputStream output = new ByteArrayOutputStream();
InputStream is;
File image;
for(String path : urlList){
//判断图片的格式
int format=0;
if (path.endsWith(".emf")) {
format = XWPFDocument.PICTURE_TYPE_EMF;
} else if (path.endsWith(".wmf")) {
format = XWPFDocument.PICTURE_TYPE_WMF;
} else if (path.endsWith(".pict")) {
format = XWPFDocument.PICTURE_TYPE_PICT;
} else if (path.endsWith(".jpeg") || path.endsWith(".jpg")) {
format = XWPFDocument.PICTURE_TYPE_JPEG;
} else if (path.endsWith(".png")) {
format = XWPFDocument.PICTURE_TYPE_PNG;
} else if (path.endsWith(".dib")) {
format = XWPFDocument.PICTURE_TYPE_DIB;
} else if (path.endsWith(".gif")) {
format = XWPFDocument.PICTURE_TYPE_GIF;
} else if (path.endsWith(".tiff")) {
format = XWPFDocument.PICTURE_TYPE_TIFF;
} else if (path.endsWith(".eps")) {
format = XWPFDocument.PICTURE_TYPE_EPS;
} else if (path.endsWith(".bmp")) {
format = XWPFDocument.PICTURE_TYPE_BMP;
} else if (path.endsWith(".wpg")) {
format = XWPFDocument.PICTURE_TYPE_WPG;
} else {
logger.error("不支持的图片类型Unsupported picture: " + path +
". Expected emf|wmf|pict|jpeg|png|dib|gif|tiff|eps|bmp|wpg");
continue;
}
//计算适合文档宽高的图片EMU数值
BufferedImage read;
if(path.startsWith("http")){
output = getByteArrayOutputStreamByUrl(path);
is = new ByteArrayInputStream(output.toByteArray());
read = ImageIO.read(is);
// is被读取后需要重新写入
is = new ByteArrayInputStream(output.toByteArray());
}else {
image = new File(path);
//判断图片是否存在
if(!image.exists()){
continue;
}
read = ImageIO.read(image);
//获取图片文件流
is = new FileInputStream(path);
}
int width = Units.toEMU(read.getWidth());
int height = Units.toEMU(read.getHeight());
//1 EMU = 1/914400英寸= 1/36000 mm,15是word文档中图片能设置的最大宽度cm
double cm=5; // 图片宽度 单位cm
if(width/360000>cm){
NumberFormat f = NumberFormat.getNumberInstance();
f.setMaximumFractionDigits(0);
f.setRoundingMode(RoundingMode.UP);
Double d=width/360000/cm;
width = Integer.valueOf(f.format(width/d).replace(",",""));
height = Integer.valueOf(f.format(height/d).replace(",",""));
}
run.addPicture(is, format, path, width, height);
is.close();
output.close();
if(index!=urlList.size()-1){
run.addBreak();//换行
}
index++;
}
}catch (Exception e){
logger.error("图片写入到word失败!",e);
}
}
/**
* 将输入流保存到字节数组中,可用于后面实现多次读取该输入流的数据
* @param httpUrl
* @return
*/
public ByteArrayOutputStream getByteArrayOutputStreamByUrl(String httpUrl) {
HttpURLConnection conn = null;
try {
URL url = new URL(httpUrl);
conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(20 * 1000);
ByteArrayOutputStream output = new ByteArrayOutputStream();
IOUtils.copy(conn.getInputStream(), output);
return output;
} catch (Exception e) {
logger.error("getByteArrayOutputStreamByUrl 异常,exception is {}", e);
} finally {
try {
if (conn != null) {
conn.disconnect();
}
} catch (Exception e) {
}
}
return null;
}
导出效果图:
原文链接:https://blog.csdn.net/weixin_42949219/article/details/124445069