通过BigExcelWriter导出包含数据和图片的excel表,涉及到sheet.createDrawingPatriarch()画图对象,涉及到url转二进制数据

文章目录

  • 通过BigExcelWriter导出包含数据和图片的excel表,涉及到sheet.createDrawingPatriarch()画图对象,涉及到url转二进制数据
  • 前言
    • 创作来之不易可点一颗小心心
  • 一、BigExcelWriter是什么?
  • 二、使用步骤
    • 1.引入库
    • 2.写入数据
  • 总结
    • 另外的注意点:
      • anchor.setAnchorType(ClientAnchor.AnchorType.MOVE_AND_RESIZE);有四个参数,需要大家伙去尝试一下每个参数的效果噢!!!

前言

创作来之不易可点一颗小心心

一、BigExcelWriter是什么?

说明:BigExcelWriter为hutool中的一个工具类,可以实现大量数据输出,采用ExcelWriter容易引起内存溢出,因此有了BigExcelWriter,使用方法与ExcelWriter完全一致。

二、使用步骤

1.引入库

代码如下(示例):

 <dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.0.7</version></dependency>

2.写入数据

代码如下(示例):

/**
*list为写进表中的数据。
*例如:我从数据库中查出来只有一条数据的话,那我的list.get(0):id--->1age--->12
*
*inputFields为表头
*
*/
private void getExcel(List<Map<String, Object>> list, List<xxxField> inputFields) throws UnsupportedEncodingException {RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();HttpServletResponse response = ((ServletRequestAttributes) requestAttributes).getResponse();//excel大数据生成BigExcelWriter writer=new BigExcelWriter();Workbook workbook = writer.getWorkbook();Sheet sheet = writer.getSheet();//设置默认高度sheet.setDefaultRowHeight((short) 1000);//构建画图对象Drawing<?> patriarch = sheet.createDrawingPatriarch();//遍历inputFields表头,也就相当于遍历列。for(int i=0;i<inputFields.size();i++){KarmaField field=inputFields.get(i);//给表头设置别名,最后导入的数据中的表头是中文:field.getFieldNameCn()if(!StringUtils.isEmpty(field.getFieldNameCn())){writer.addHeaderAlias(field.getFieldNameEn(),field.getFieldNameCn());}//日期格式列宽长一点if(field.getFieldType().equals("date")||field.getFieldType().equals("datetime")||field.getFieldType().equals("timestamp")){sheet.setColumnWidth(i,20*256);}//如果字段类型为text的话则列宽一点if (field.getFieldType().equals("text")){sheet.setColumnWidth(i,60*256);}//1 == field.getIfImg()意思为判断表头遍历这一列是否是存图片的列,如果为1的话则把图片写到对应的位置去。if (1 == field.getIfImg()){sheet.setColumnWidth(i,20*256);//遍历list相当于遍历行for (int j = 0; j < list.size(); j++) {//如果ifImg为1,取出fieIdNameEn,然后遍历list,取出key为fieIdNameEn的value值。此vuler值则是图片存到服务器中的路径//类似与:https://data.xxx.cn/pic/c957bb12-cb52-47c5-8171-0e7f944b848e.jpeg(可直接在浏览器打开的图片)String pictureUrl = (String) list.get(j).get(field.getFieldNameEn());//j为行号,i为列号//为了保险起见,可能pictureUrl 中为空,所以判断一下,不然会报空指针if (jodd.util.StringUtil.isNotBlank(pictureUrl)){//WriteImgUtil.writeImg()为自定义写入图片到excel表中的方法,见一下WriteImgUtil工具类。WriteImgUtil.writeImg(j + 1, i, pictureUrl, workbook, patriarch);//如果不加此操作的话,该单元格里面虽然写入了图片,但同时也会把list中遍历出的pictureUrl 路径给写到单元格去。list.get(j).remove(field.getFieldNameEn());list.get(j).put(field.getFieldNameEn(),"");}}}}//设置日期格式StyleSet style = writer.getStyleSet();CellStyle cellStyle = style.getCellStyleForDate();cellStyle.setDataFormat(writer.getWorkbook().createDataFormat().getFormat("yyyy-MM-dd HH:mm:ss"));//这是关键的一步,就是把list写进excel表中。如果不是要写入图片的话,前面写图片的业务代码可以都不要。只要 writer.write(list);便可以直接写入excel表中。writer.write(list);response.reset();response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("哈哈哈哈.xlsx", "UTF-8"));response.setContentType("multipart/form-data");try {writer.flush(response.getOutputStream());} catch (IOException e) {e.printStackTrace();} finally {if (writer!=null){//关闭writer 释放内存writer.close();}}}

该WriteImgUtil 分为两步:
1.第一步,解析传递过来的图片路径类似于:https://data.xxx.gov.cn/pic/c957bb12-cb52-47c5-8171-0e7f944b848e.jpeg(可以直接在浏览器打开)返回的参数是图片的二进制数据。
2.第二步,调用绘图对象把二进制数据写入到excel中对应的位置中去。

注意点:这里只是把图片导入到以.xlsx后缀的excel表中。如果想导入到以.xls后缀的excel表的话,只需要改一下anchor属性就可以了。

public class WriteImgUtil {/*** 把图片写入excel中* @param row 写入的行* @param col 写入的列* @param pictureUrl 可打开的图片的地址* @param workbook 工作簿* @param patriarch 绘图对象*/public static void writeImg(Integer row, Integer col, String pictureUrl, Workbook workbook, Drawing<?> patriarch){try {if (StringUtils.isNotBlank(pictureUrl)) {URL url = new URL(pictureUrl);//打开链接HttpURLConnection conn = (HttpURLConnection) url.openConnection();//设置请求方式为"GET"conn.setRequestMethod("GET");//超时响应时间为5秒  qconn.setConnectTimeout(5 * 1000);//通过输入流获取图片数据InputStream inStream = conn.getInputStream();//得到图片的二进制数据,以二进制封装得到数据,具有通用性byte[] data = readInputStream(inStream);//anchor主要用于设置图片的属性XSSFClientAnchor anchor = new XSSFClientAnchor(0, 0, 1023, 1023, col.shortValue(), row.shortValue(), col.shortValue()+1, row.shortValue()+1);anchor.setAnchorType(ClientAnchor.AnchorType.MOVE_AND_RESIZE);patriarch.createPicture(anchor, workbook.addPicture(data, XSSFWorkbook.PICTURE_TYPE_JPEG));}} catch (IOException e) {e.printStackTrace();} catch (Exception e) {e.printStackTrace();}}/*** 通过输入流获得二进制图片数据* @param inStream* @return* @throws Exception*/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();}
}

总结

这个总结耗费大量时间,在如何控制行高这里找了大量的资料,然而还是没有更好的办法,只能用 sheet.setDefaultRowHeight((short) 1000);设置默认高度。如果有图片的话,并不能做到自适应的程度。只能设置图片所在的单元格的列宽,让其excel看起来正常一点。


如下图所示,可以自定义姓名和任务肖像的列框,但是只能设置默认高度。所以是非常丑的。所以到最后我只有缩小图片的列宽让图片尽可能的正常。希望大家能有好的建议留在评论区(百度翻烂了都没有找到)!!!

最后的效果:

另外的注意点:

anchor.setAnchorType(ClientAnchor.AnchorType.MOVE_AND_RESIZE);有四个参数,需要大家伙去尝试一下每个参数的效果噢!!!

通过BigExcelWriter导出包含数据和图片的excel表,涉及到sheet.createDrawingPatriarch()画图对象,涉及到url转二进制数据相关推荐

  1. 合并多个excel表中相同sheet的数据

    合并多个excel表中相同sheet的数据 1.把要进行汇总的表(相同格式)放在同一个文件夹,如下图,然后把同样格式的空表也一同放在文件夹下,如下图(对文件夹的名字,路径没有要求) 2.点击打开 空表 ...

  2. 如何将.TXT中的数据正确的导入excel表中

    将.txt中的文本:01 03 20 10 6C 19 22 10 6D 10 6B 10 6B 10 6B 10 6B 10 6A 10 6A 10 6A 10 6B 10 6B 10 6B 10 ...

  3. java freemarker 图片_java通过freemarker导出包含富文本图片的word文档

    废话不多说,进入正题! 本文重点在于:对富文本图片的导出(基础的freemarker+word模板导出这里不做详细解说哈) (ps:大神的东西太深奥~~懵逼了 一周才搞定,为了方便后来在更加简单,清晰 ...

  4. python 查询mysql数据导出excl_python查询mysql并生成excel表

    需求说明 开发不愿意单独为某个项目做后台 并且运营那边需要合并多个表的数据 因此找上了我. 要求每周执行一次.月初也执行一次 要查询2个mysql数据库多个表并生成excel表 我的想法 找开发要sq ...

  5. datatable如何生成级联数据_如何把Excel表数据批量生成条形码

    条形码属于一维条码,是将宽度不等的多个黑条和空白,按照一定的编码规则排列,用以表达一组信息的图形标识符,条形码的种类比较多,比如常用的Code128码,Code39码,Code93码,EAN-13码, ...

  6. python怎么从excel获取数据_python如何读取excel表数据

    python读取excel表数据的方法:首先安装Excel读取数据的库xlrd:然后获取Excel文件的位置并且读取进来:接着读取指定的行和列的内容,并将内容存储在列表中:最后运行程序即可. pyth ...

  7. matlab把某一列作为x轴,excel表格怎么把某一列数据作为x轴-EXCEL表中的两列数据怎样作为X轴和Y轴放在图表里...

    excel表格制作坐标图,如何设定某列(数据直接非线... 只能邦你一半.x轴调整我会,生成图表--图表上方右键--选择数据--水平(分类)标签编辑,点进去,选择你要作为X轴的数据区域,即可. 使用e ...

  8. Excel表怎么快速移动整行、整列、整块区域数据

    在Excel操作数据过程中,当在数据区域中进整(多)行或列移动时,采用正确的操作技巧,省事且准确. 步骤如下: 1.用Excel打开文件.如下图 2.选中要移动的数据整行. 3.选中数据后,将光标移至 ...

  9. 在excel中如何筛选重复数据_如何将Excel表中重复数据筛选出来?

    在使用Excel表格时,当Excel表格数据在数量庞大的情况下,输入重复数据在所难免.但为确保表格最终统计分析结果的准确性,需要快速筛选出重复的数据,进行删除标记等多重处理.人工手动校对数据即浪费时间 ...

最新文章

  1. SubVersion和Subclipse的简单使用方法
  2. 让Exchange 2010 (2007适用)可以收发外部邮件
  3. Makefile中打印变量
  4. 计算属性|| 计算属性与方法的区别:计算属性是基于它们的依赖进行缓存的 ;方法不存在缓存||侦听器
  5. Linux-服务器远程控制
  6. JVM运行时结构、Java内存管理、JVM实例、HotSpot VM对象的创建、内存布局和访问定位
  7. 讲二次搜索树转化为排序的双向链表
  8. Apache Karaf遇到Apache HBase
  9. 万向区块链首席经济学家:央行数字货币与狭义银行是不同层次的概念
  10. FTP:226 transfer done but failed to open directory
  11. VB 屏幕融化超级恶搞程序代码
  12. 阿里无人车,正在高速过弯
  13. python自学要多久-怎么自学python,大概要多久?
  14. Gstreamer之QT程序无法找到Gstreamer1.0 pulseaudio插件(二十八)
  15. mysql用root账户建立用户和赋予权限
  16. 如何搭建一个vue项目(完整步骤)
  17. 2021年全国居住场所火灾死亡人数、受伤人数、火灾发生原因及造成直接财产损失分析[图]
  18. relative学习笔记
  19. codeblock-(no debugging symbols found)(已解决)
  20. 郑州大学编译原理实验三算符优先分析算法JAVA

热门文章

  1. 激光诱导击穿光谱电化学方法对环境中重金属离子的检测研究获进展
  2. 2019年全国1卷理数第20题
  3. input标签的事件之oninput事件
  4. 重磅!认知智能真的来了?且看道翰天琼认知智能三大技术体系!
  5. Thumbnails压缩图片到指定大小
  6. vue根据返回路径下载xml文件
  7. php plupload,thinkphp5 框架结合plupload实现图片批量上传功能示例
  8. 综合评价与决策方法04——灰色关联分析法
  9. 山东大学软件学院项目实训-创新实训-SDUMeeting(六)
  10. 综合扫描工具x-scan使用教程