赞
踩
将网页数据导出为Excel恐怕是日常开发遇到非常多的需求了,以往的操作可能会稍显复杂,今天学习了一个新的神器,分享给大家,话不多说,上代码
我们选用easyExcel作为技术栈,首先引入依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>2.2.6</version>
</dependency>
为了方便操作,我们首先建立一个与Excel对应的实体类
package com.****.energy.nat.entity; /** * @author ascool_zh * @create 2021-02-9:59 */ @Data @ContentRowHeight(35) @HeadRowHeight(20) public class ExcelModel { @ExcelProperty(value="条码号",index = 0) @ColumnWidth(23) private String barCode; @ExcelProperty(value="条形码",index = 1) @ColumnWidth(23) private File barCodeImg; } /** * ExcelProperty index 指定写到第几列,默认根据成员变量排序。value指定写入的名称,默认成员变量的名字,多个value可以参照快速开始中的复杂头 * ExcelIgnore 默认所有字段都会写入excel,这个注解会忽略这个字段 * DateTimeFormat 日期转换,将Date写到excel会调用这个注解。里面的value参照java.text.SimpleDateFormat * NumberFormat 数字转换,用Number写excel会调用这个注解。里面的value参照java.text.DecimalFormat * ExcelIgnoreUnannotated 默认不加ExcelProperty的注解的都会参与读写,加了不会参与 */
写Excel
一个简单的例子
@Data
public class DemoData {
@ExcelProperty("字符串标题")
private String string;
@ExcelProperty("日期标题")
private Date date;
@ExcelProperty("数字标题")
private Double doubleData;
/**
* 忽略这个字段
*/
@ExcelIgnore
private String ignore;
}
/**
* 指定写入的列
* <p>1. 创建excel对应的实体对象 参照{@link IndexData}
* <p>2. 使用{@link ExcelProperty}注解指定写入的列
* <p>3. 直接写即可
*/
@Test
public void indexWrite() {
//文件名,文件会被存入到这个路径
String fileName = TestFileUtil.getPath() + "indexWrite" + System.currentTimeMillis() + ".xlsx";
// 这里 需要指定写用哪个class去写,DemoData,然后写到第一个sheet,名字为模板 然后文件流会自动关闭
EasyExcel.write(fileName, DemoData.class).sheet("模板").doWrite(data());
}
批量写
/** * 重复多次写入 * <p> * 1. 创建excel对应的实体对象 参照{@link ComplexHeadData} * <p> * 2. 使用{@link ExcelProperty}注解指定复杂的头 * <p> * 3. 直接调用二次写入即可 */ @Test public void repeatedWrite() { // 方法1 如果写到同一个sheet String fileName = TestFileUtil.getPath() + "repeatedWrite" + System.currentTimeMillis() + ".xlsx"; ExcelWriter excelWriter = null; try { // 这里 需要指定写用哪个class去写 excelWriter = EasyExcel.write(fileName, DemoData.class).build(); // 这里注意 如果同一个sheet只要创建一次 WriteSheet writeSheet = EasyExcel.writerSheet("模板").build(); // 去调用写入,这里我调用了五次,实际使用时根据数据库分页的总的页数来 for (int i = 0; i < 5; i++) { // 分页去数据库查询数据 这里可以去数据库查询每一页的数据 List<DemoData> data = data(); excelWriter.write(data, writeSheet); } } finally { // 千万别忘记finish 会帮忙关闭流 if (excelWriter != null) { excelWriter.finish(); } } // 方法2 如果写到不同的sheet 同一个对象 fileName = TestFileUtil.getPath() + "repeatedWrite" + System.currentTimeMillis() + ".xlsx"; try { // 这里 指定文件 excelWriter = EasyExcel.write(fileName, DemoData.class).build(); // 去调用写入,这里我调用了五次,实际使用时根据数据库分页的总的页数来。这里最终会写到5个sheet里面 for (int i = 0; i < 5; i++) { // 每次都要创建writeSheet 这里注意必须指定sheetNo 而且sheetName必须不一样 WriteSheet writeSheet = EasyExcel.writerSheet(i, "模板" + i).build(); // 分页去数据库查询数据 这里可以去数据库查询每一页的数据 List<DemoData> data = data(); excelWriter.write(data, writeSheet); } } finally { // 千万别忘记finish 会帮忙关闭流 if (excelWriter != null) { excelWriter.finish(); } } // 方法3 如果写到不同的sheet 不同的对象 fileName = TestFileUtil.getPath() + "repeatedWrite" + System.currentTimeMillis() + ".xlsx"; try { // 这里 指定文件 excelWriter = EasyExcel.write(fileName).build(); // 去调用写入,这里我调用了五次,实际使用时根据数据库分页的总的页数来。这里最终会写到5个sheet里面 for (int i = 0; i < 5; i++) { // 每次都要创建writeSheet 这里注意必须指定sheetNo 而且sheetName必须不一样。这里注意DemoData.class 可以每次都变,我这里为了方便 所以用的同一个class 实际上可以一直变 WriteSheet writeSheet = EasyExcel.writerSheet(i, "模板" + i).head(DemoData.class).build(); // 分页去数据库查询数据 这里可以去数据库查询每一页的数据 List<DemoData> data = data(); excelWriter.write(data, writeSheet); } } finally { // 千万别忘记finish 会帮忙关闭流 if (excelWriter != null) { excelWriter.finish(); } } }
图片写
@Data @ContentRowHeight(100) @ColumnWidth(100 / 8) public class ImageData { private File file; private InputStream inputStream; /** * 如果string类型 必须指定转换器,string默认转换成string */ @ExcelProperty(converter = StringImageConverter.class) private String string; private byte[] byteArray; /** * 根据url导出 * * @since 2.1.1 */ private URL url; }
/** * 图片导出 * <p> * 1. 创建excel对应的实体对象 参照{@link ImageData} * <p> * 2. 直接写即可 */ @Test public void imageWrite() throws Exception { String fileName = TestFileUtil.getPath() + "imageWrite" + System.currentTimeMillis() + ".xlsx"; // 如果使用流 记得关闭 InputStream inputStream = null; try { List<ImageData> list = new ArrayList<ImageData>(); ImageData imageData = new ImageData(); list.add(imageData); String imagePath = TestFileUtil.getPath() + "converter" + File.separator + "img.jpg"; // 放入五种类型的图片 实际使用只要选一种即可 imageData.setFile(new File(imagePath)); inputStream = FileUtils.openInputStream(new File(imagePath)); imageData.setString(imagePath); imageData.setInputStream(inputStream); imageData.setByteArray(FileUtils.readFileToByteArray(new File(imagePath))); imageData.setUrl(new URL( "https://raw.githubusercontent.com/alibaba/easyexcel/master/src/test/resources/converter/img.jpg")); EasyExcel.write(fileName, ImageData.class).sheet().doWrite(list); } finally { if (inputStream != null) { inputStream.close(); } } }
Web写
@RequestMapping("/exportExcel") public void exportExcel(String startCode, int count, String netCode,String netName,HttpServletResponse response) throws IOException { //后台查出的数据 List<Map<String, Object>> qryPrintList = printBarcodeService.getPrintList(startCode, count, netCode); //创建存放ExcelModel的List,你可以理解为一个ExcelModel为一行数据,其属性barCode和barCodeImg即是行所要填的值 List<ExcelModel> list = new ArrayList<ExcelModel>(); String msg = ""; String path = ""; if (count <= 5000) { for (Map<String, Object> map : qryPrintList) { msg = (String) map.get("barCode"); path = barcodeFilepath + msg + ".png"; ExcelModel excelModel = new ExcelModel(); try { //对ExcelModel对象赋值,相当于你填写每行的记录 list.add(excelModel); //msg和path都已经赋值 excelModel.setBarCode(msg); excelModel.setBarCodeImg(new File(path)); } catch (Exception e) { System.out.println(e); } } //设置一些属性 response.setContentType("application/vnd.ms-excel"); response.setCharacterEncoding("utf-8"); // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系 String fileName = URLEncoder.encode(netName+"条码表", "UTF-8").replaceAll("\\+", "%20"); response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx"); //执行,list中已经包含多个ExcelModel,即相当于填写了多条记录 EasyExcel.write(response.getOutputStream(), ExcelModel.class).sheet("条码表").doWrite(list); } }
//前端避免使用Ajax,直接用window.location.href更方便
function exportExcel(){
var startCode = $("#startCode").val();
var count = $("#count").val();
var netCode = $("#checkNet").val();
var netName = $("#checkNet").combobox('getText');
window.location.href = "nat/print/exportExcel?startCode="+startCode+"&count="+count+"&netCode="+netCode+"&netName="+netName;
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。