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