需求
导出人员的信息并且加上人员的照片至EXCEL中
完整的代码
//创建一个表格 HSSFWorkbook wb = new HSSFWorkbook(); HSSFSheet sheet = wb.createSheet(); //需要导出的人员信息 List<StaffBO> boList =staffService.findStaffList(searchBO); if(boList != null && boList.size() >0) { //一定要放在循环外,只能声明一次 HSSFPatriarch patriarch = sheet.createDrawingPatriarch(); for(int i=0; i<boList.size(); i++) { HSSFRow dataRow = sheet.createRow(i+1);//数据行 HSSFCell dataCell0 = dataRow.createCell(0);//每行的第一列存放照片 drawPictureInfoExcel(wb,patriarch,i+1,obj.getLaborStore().getPhoto());//i+1代表当前的行 } } // 关于HSSFClientAnchor(dx1,dy1,dx2,dy2,col1,row1,col2,row2)的参数,有必要在这里说明一下: // dx1:起始单元格的x偏移量, // dy1:起始单元格的y偏移量, // dx2:终止单元格的x偏移量, // dy2:终止单元格的y偏移量, // col1:起始单元格列序号,从0开始计算; // row1:起始单元格行序号,从0开始计算, // col2:终止单元格列序号,从0开始计算; // row2:终止单元格行序号,从0开始计算, private void drawPictureInfoExcel(HSSFWorkbook wb,HSSFPatriarch patriarch,int rowIndex,String pictureId) { //rowIndex代表当前行 try { String pictureUrl = null; if(StringUtils.isNotBlank(pictureId)) { UploadFile pictureFile = uploadFileService.get(pictureId); if(pictureFile != null) { pictureUrl = pictureFile.getPath();//获取人员照片的地址 } logger.info("人员照片地址为:"+pictureUrl); } if(StringUtils.isNotBlank(pictureUrl)) { URL url = new URL(pictureUrl); //打开链接 HttpURLConnection conn = (HttpURLConnection)url.openConnection(); //设置请求方式为"GET" conn.setRequestMethod("GET"); //超时响应时间为5秒 conn.setConnectTimeout(5 * 1000); //通过输入流获取图片数据 InputStream inStream = conn.getInputStream(); //得到图片的二进制数据,以二进制封装得到数据,具有通用性 byte[] data = readInputStream(inStream); //anchor主要用于设置图片的属性 HSSFClientAnchor anchor = new HSSFClientAnchor(0, 0, 1023, 250,(short) 0, rowIndex, (short) 0, rowIndex); //Sets the anchor type (图片在单元格的位置) //0 = Move and size with Cells, 2 = Move but don't size with cells, 3 = Don't move or size with cells. anchor.setAnchorType(0); patriarch.createPicture(anchor, wb.addPicture(data, HSSFWorkbook.PICTURE_TYPE_JPEG)); } } catch (IOException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } }
导出的结果如下:
解决说明
1. 获取网络中的图片资源
百度了一下,一共找到两种
第一种:
//pictureUrl是人员照片的地址 URL url = new URL(pictureUrl); BufferedImage bufferImg = ImageIO.read(url); ByteArrayOutputStream byteArrayOut = new ByteArrayOutputStream(); ImageIO.write(bufferImg, "jpg", byteArrayOut); byte[] data = byteArrayOut.toByteArray(); //最终导入时所需要的图片要转换为byte[]
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 1
- 2
- 3
- 4
- 5
- 6
- 7
但是发现一个问题,在本地测试是可以正常导出的,到了服务器中就不能导出,记录了一下导出时的日志,发现图片的地址是这样的
http://www.xxx.cn:80/appfile//modules/apphr/staff/1481865941995.png
- 1
- 1
多了一个端口号,去掉端口号时可以正常导出的,把地址直接黏贴到浏览器中也是可以访问的,不得其解,问了一下别人也没得出原因
第二种(本地和服务器都可以):
//java.net.URL //java.net.HttpURLConnection; URL url = new URL(pictureUrl); //打开链接 HttpURLConnection conn = (HttpURLConnection)url.openConnection(); //设置请求方式为"GET" conn.setRequestMethod("GET"); //超时响应时间为5秒 conn.setConnectTimeout(5 * 1000); //通过输入流获取图片数据 InputStream inStream = conn.getInputStream(); //得到图片的二进制数据,以二进制封装得到数据,具有通用性 byte[] data = readInputStream(inStream);
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
private static byte[] readInputStream(InputStream inStream) throws Exception{ ByteArrayOutputStream outStream = new ByteArrayOutputStream(); //创建一个Buffer字符串 byte[] buffer = new byte[1024]; //每次读取的字符串长度,如果为-1,代表全部读取完毕 int len = 0; //使用一个输入流从buffer里把数据读取出来 while( (len=inStream.read(buffer)) != -1 ){ //用输出流往buffer里写入数据,中间参数代表从哪个位置开始读,len代表读取的长度 outStream.write(buffer, 0, len); } //关闭输入流 inStream.close(); //把outStream里的数据写入内存 return outStream.toByteArray(); }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
2. 导入到EXCEL中
导出使用的时POI,主要用到两个类:
HSSFPatriarch(负责再excel中创建图片)、HSSFClientAnchor(负责图片再excel中的位置)
- 1
- 1
代码如下:
//创建一个工作簿
HSSFWorkbook wb = new HSSFWorkbook();
//创建一个表格
HSSFSheet sheet = wb.createSheet();
//一定要放在循环外,只能声明一次
HSSFPatriarch patriarch = sheet.createDrawingPatriarch();
for(int i=0; ...; i++) { //调用插入图片到excel的方法 drawPictureInfoExcel(wb,patriarch,i,"图片地址"); }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
//rowIndex代表的是当前的行标 private void drawPictureInfoExcel(HSSFWorkbook wb,HSSFPatriarch patriarch,int rowIndex,String pictureId) { try { //anchor主要用于设置图片的属性 HSSFClientAnchor anchor = new HSSFClientAnchor(0, 0, 1023, 250,(short) 0, rowIndex, (short) 0, rowIndex); //Sets the anchor type (图片在单元格的位置) //0 = Move and size with Cells, 2 = Move but don't size with cells, 3 = Don't move or size with cells. anchor.setAnchorType(0); patriarch.createPicture(anchor, wb.addPicture(data, HSSFWorkbook.PICTURE_TYPE_JPEG)); } catch (IOException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } }