Java读写excel方法大全,对特定的数据给上特定的背景颜色,加生备注信息等等。

原生poi

原生poi对excel操作非常灵活。导出的时候可以对特定的数据给上特定的背景颜色,加生备注信息等等。

原生poi导入

  InputStream is = null;
        try {
            is = file.getInputStream();//获取到excel的字节流(读者可以使用自己的方式获取)
            XSSFWorkbook xssfWorkbook = new XSSFWorkbook(is);
            //第0个sheet
            XSSFSheet sheet = xssfWorkbook.getSheetAt(0);
           int row sheet.getLastRowNum(); // 获取最大行数索引值
            List<String> values = new ArrayList<>();
            //0遍历到最后一行
            for(int r=0;r<row;r++){
                XSSFRow row = sheet.getRow(r);
               //获取第R行的第1个数值 
                String val1 = ExcelUtil.getXSSFCellValue(row.getCell(1));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

原生poi导出

 // 创建excel文件对象
        XSSFWorkbook wb = new XSSFWorkbook();
        // 创建excel的表单对象
        Sheet warnDataSheet = wb.createSheet("sheetName");
        Sheet allDataSheet = wb.createSheet("sheetName2");
        //浅蓝色背景-微软雅黑 10号
       CellStyle headStyle = ExcelUtils.getCellStyle(wb, Font.COLOR_NORMAL, IndexedColors.PALE_BLUE.getIndex(), HorizontalAlignment.CENTER);
        //白色背景-微软雅黑 10号
       CellStyle dataStyle= ExcelUtils.getCellStyle(wb, IndexedColors.BLACK.index, IndexedColors.WHITE.getIndex(),HorizontalAlignment.CENTER)   

        Row row = sheet.createRow(0);
        // 用行对象得到Cell对象
        Cell cell = row.createCell(0);
        cell.setCellValue("表头01");
        cell.setCellStyle(headStyle);
         cell = row.createCell(0);
        cell.setCellValue("表头02");
        cell.setCellStyle(headStyle);
 
        Row row = sheet.createRow( 1);
        Cell createCell = row.createCell(0);
        createCell.setCellValue("数据1");
        createCell.setCellStyle(dataStyle);
        createCell = row.createCell(0);
        createCell.setCellValue("数据2");
        createCell.setCellStyle(dataStyle);
        //给数据2加批注
         ExcelUtils.addComment(createCell,"批注信息",warnDataSheet );
      
        String fileName =  "excel文件名称";
        ExcelUtils.exportExcel(response,wb,fileName);
ExcelUtil
 public static void exportExcel(HttpServletResponse response, XSSFWorkbook wb,String fileName ) {
        try {
            fileName = URLEncoder.encode(fileName, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        // 设置响应头
        response.setCharacterEncoding("utf-8");
        response.setContentType("application/vnd.ms-excel;charset=utf-8");
        response.setHeader("Content-Disposition",
            "attachment;filename=" + fileName+".xls");
        try ( ServletOutputStream outputStream = response.getOutputStream()){
            wb.write(outputStream);
            outputStream.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
           if(wb!=null){
               try {
                   wb.close();
               } catch (IOException e) {
                   e.printStackTrace();
               }
           }
        }
    }
    /**
     * 获取单元格样式
     * @param wb workbook
     * @param fontColor 字体颜色(IndexedColors.RED.getIndex())
     * @param groundColor 背景颜色IndexedColors.CORNFLOWER_BLUE.getIndex()
     * @return void
     * @date 2022-05-05 09:06:35
     */
    public static CellStyle getCellStyle( XSSFWorkbook wb,short fontColor,short groundColor, HorizontalAlignment var1){
        CellStyle style = wb.createCellStyle();
        XSSFFont font = wb.createFont();
        font.setColor(fontColor);
        font.setFontName("微软雅黑");
        font.setFontHeightInPoints((short)10);
        style.setFont(font);
        style.setFillForegroundColor(groundColor);
        style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        style.setBorderBottom(BorderStyle.THIN); //下边框
        style.setBorderLeft(BorderStyle.THIN);//左边框
        style.setBorderTop(BorderStyle.THIN);//上边框
        style.setBorderRight(BorderStyle.THIN);//右边框
        style.setAlignment(var1);
        return style;
    }
     /**
     * 合并单元格
     * @return java.util.Map<java.lang.Integer,org.apache.poi.ss.usermodel.CellStyle>
     * @date 2022-05-05 17:04:22
     */
    public static void  mergedCell(Sheet sheet,int sx,int sy,int tx,int ty){
        sheet.addMergedRegion(new CellRangeAddress(sx,sy,tx,ty));
    }
    
    /**
     * 给Cell添加批注
     * @param cell 单元格
     * @param value 批注内容
     * @date 2022-05-05 17:04:22
     */
    public static void addComment(Cell cell, String value, Sheet sheet) {
        //设置单元格中的批注
        Drawing draw = sheet.createDrawingPatriarch();
        //此处八个参数   前四个参数为两个坐标点(从a坐标到b坐标)后四个参数   为  编辑和显示批注时的大小(看需求调整)
        Comment comment = draw.createCellComment(new XSSFClientAnchor(1,1,8,8,3,3,5,1));
        //输入批注信息
        comment.setString(new XSSFRichTextString(value));
        //添加作者,选中B5单元格,看状态栏
        comment.setAuthor("sys");
        //将批注添加到单元格对象中
        cell.setCellComment(comment);
    }
    public static String getXSSFCellValue(XSSFCell xssfCell) {
        String cellValue = null;
        if (xssfCell != null) {
            CellType cellType = xssfCell.getCellType();
            if (CellType.STRING.equals(cellType)) {
                cellValue = xssfCell.getStringCellValue();
            } else if (CellType.NUMERIC.equals(cellType)) {
                double d = xssfCell.getNumericCellValue();
                cellValue = df.format(d);
            } else if (CellType.BOOLEAN.equals(cellType)) {
                cellValue = String.valueOf(xssfCell.getBooleanCellValue());
            } else if (CellType.FORMULA.equals(cellType)) {
                cellValue = String.valueOf(xssfCell.getCellFormula());
            }
        }
        return cellValue;
    }

EasyExcel-list集合填充excel导出

public void exportIndExcel(HttpServletResponse response, List<String> indIds) throws IOException {
		try {
			String fileName = URLEncoder.encode("指标填报模板", "UTF-8");
			if(indIds!=null&&indIds.size()>0){
				fileName = URLEncoder.encode("指标数据表", "UTF-8");
			}
			/*	getIndDefData返回数据如下   List<List<String>> 对于行列数据
		 	List<List<String>> dataOne = new ArrayList<>();
		    List<List<String>> dataTwo = new ArrayList<>();
		   Map<String,List<List<String>>> value = new HashMap<>();*/
			Map<String, List<List<String>>> map = getIndDefData(indIds);
			List<List<String>> datasOne = map.get("dataOne");
			List<List<String>> datasTwo = map.get("dataTwo");


             /*getIndDefHeaders返回数据
             List<List<String>> heads= new ArrayList<>();
			List<String> column0 = new ArrayList<>();
			column0.add("指标目录");
			heads.add(column0);
	
			List<String> column4 = new ArrayList<>();
			column4.add("指标类型");
			heads.add(column4); */
			List<List<String>> headersOne = getIndDefHeaders(1);

			List<List<String>> headersTwo = getIndDefHeaders(2);

			response.setContentType("application/vnd.ms-excel");
			response.setCharacterEncoding("utf-8");
			response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
			ExcelWriterBuilder writerBuilder = EasyExcel.write(response.getOutputStream());
			ExcelWriter build = writerBuilder.build();
			WriteSheet one = EasyExcel.writerSheet(0, "基础指标").head(headersOne).build();
			WriteSheet two = EasyExcel.writerSheet(1, "衍生指标").head(headersTwo).build();
			build.write(datasOne,one);
			build.write(datasTwo,two);
			build.finish();
		} catch (Exception e) {
			
		}
	}

根据对象读写

对象

public class DemoData {
    /**
     * 强制读取第三个 这里不建议 index 和 name 同时用,要么一个对象只用index,要么一个对象只用name去匹配
     */
    @ExcelProperty(index = 2)
    private Double doubleData;
    /**
     * 用名字去匹配,这里需要注意,如果名字重复,会导致只有一个字段读取到数据
     */
    @ExcelProperty("字符串标题")
    private String string;
    @ExcelProperty("日期标题")
    private Date date;
}

监听器

监听器构造器可以传对象进来,
list获取读取的数据,
xxxService对数据进行保存

// 如果没有特殊说明,下面的案例将默认使用这个监听器
public class DemoDataListener extends AnalysisEventListener<DemoData> {

    List<DemoData> list = new ArrayList<DemoData>();
    
    /**
     * 如果使用了spring,请使用这个构造方法。每次创建Listener的时候需要把spring管理的类传进来
     */
    public DemoDataListener() {

    }

    /**
     * 这个每一条数据解析都会来调用
     *
     * @param data
     * @param context
     */
    @Override
    public void invoke(DemoData data, AnalysisContext context) {

        ReadSheetHolder readSheetHolder = analysisContext.readSheetHolder();
        String sheetName = readSheetHolder.getSheetName()
        //sheetName sheet名称 
        System.out.println("解析到一条数据:{}", JSON.toJSONString(data));
        list.add(data);
    }

    /**
     * 所有数据解析完成了 都会来调用
     *
     * @param context
     */
    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        System.out.println(JSON.toJSONString(list));
    }
}

导入导出

简单例子

/**
	excel文件的下载
*/
@GetMapping("download")
public void download(HttpServletResponse response) throws IOException {
    response.setContentType("application/vnd.ms-excel");
    response.setCharacterEncoding("utf-8");
    String  fileName = URLEncoder.encode("指标数据表", "UTF-8");
    response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
    // data()方法是写入的数据,结果是List<DemoData>集合
        EasyExcel.write(response.getOutputStream(), DownloadData.class).sheet("模板").doWrite(data());
}

/**
	excel文件的上传
*/
@PostMapping("upload")
@ResponseBody
public String upload(MultipartFile file) throws IOException {
    EasyExcel.read(file.getInputStream(), DemoData.class, new DemoDataListener()).sheet().doRead();
    return "success";
}
    

导入多个sheet

@Test
public void repeatedRead() {
    String fileName = "demo.xlsx";
    // 读取全部sheet
    // 这里需要注意 DemoDataListener的doAfterAllAnalysed 会在每个sheet读取完毕后调用一次。然后所有sheet都会往同一个DemoDataListener里面写
    EasyExcel.read(fileName, DemoData.class, new DemoDataListener()).doReadAll();

    // 读取部分sheet
    fileName = "demo.xlsx";
    ExcelReader excelReader = EasyExcel.read(fileName).build();
    // 这里为了简单 所以注册了 同样的head 和Listener 自己使用功能必须不同的Listener
    // readSheet参数设置读取sheet的序号
    ReadSheet readSheet1 =
        EasyExcel.readSheet(0).head(DemoData.class).registerReadListener(new DemoDataListener()).build();
    ReadSheet readSheet2 =
        EasyExcel.readSheet(1).head(DemoData.class).registerReadListener(new DemoDataListener()).build();
    // 这里注意 一定要把sheet1 sheet2 一起传进去,不然有个问题就是03版的excel 会读取多次,浪费性能
    excelReader.read(readSheet1, readSheet2);
    // 这里千万别忘记关闭,读的时候会创建临时文件,到时磁盘会崩的
    excelReader.finish();
}

导出多个sheet

@GetMapping("/test")
	public void testExport(HttpServletResponse response) throws IOException {
		String fileName = URLEncoder.encode("指标填报模板", "UTF-8");
		response.setContentType("application/vnd.ms-excel");
		response.setCharacterEncoding("utf-8");
		response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
		ExcelWriter build1 = EasyExcel.write(response.getOutputStream(), DownloadData.class).build();
		WriteSheet writeSheet = EasyExcel.writerSheet(1,"sheet01").build();
		WriteSheet writeSheet02 = EasyExcel.writerSheet(2,"sheet02").build();

		List<DownloadData> data1 = new ArrayList<>();
		//省略数据

		List<DownloadData> data2 = new ArrayList<>();
		//省略数据

		//sheet00  第一页
		build1.write(data1,writeSheet);
		//sheet01 第二页
		build1.write(data2,writeSheet02);

		build1.finish();
	}

导出指定列

@Test
public void excludeOrIncludeWrite() {
    String fileName = "excludeOrIncludeWrite" + System.currentTimeMillis() + ".xlsx";

    // 忽略 date 不导出
    Set<String> excludeColumnFiledNames = new HashSet<String>();
    excludeColumnFiledNames.add("date");
    // 这里 需要指定写用哪个class去写,然后写到第一个sheet,名字为模板 然后文件流会自动关闭
    EasyExcel.write(fileName, DemoData.class).excludeColumnFiledNames(excludeColumnFiledNames).sheet("忽略date")
        .doWrite(data());

    fileName = "excludeOrIncludeWrite" + System.currentTimeMillis() + ".xlsx";
    // 根据用户传入字段 假设我们只要导出 date
    Set<String> includeColumnFiledNames = new HashSet<String>();
    includeColumnFiledNames.add("date");
    // 这里 需要指定写用哪个class去写,然后写到第一个sheet,名字为模板 然后文件流会自动关闭
    EasyExcel.write(fileName, DemoData.class).includeColumnFiledNames(includeColumnFiledNames).sheet("导出date")
        .doWrite(data());
}

导入列 (根据index控制)

public class IndexData {
    /**
    * 导出的excel第二列和第四列将空置
    */
    @ExcelProperty(value = "字符串标题", index = 0)
    private String string;
    @ExcelProperty(value = "日期标题", index = 2)
    private Date date;
    @ExcelProperty(value = "数字标题", index = 4)
    private Double doubleData;
}

复杂头信息

public class ComplexHeadData {
    /**
    * 主标题 将整合为一个单元格效果如下:
    * —————————————————————————
    * |          主标题        |
    * —————————————————————————
    * |字符串标题|日期标题|数字标题|
    * —————————————————————————
    */
    @ExcelProperty({"主标题", "字符串标题"})
    private String string;
    @ExcelProperty({"主标题", "日期标题"})
    private Date date;
    @ExcelProperty({"主标题", "数字标题"})
    private Double doubleData;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值