精华内容
下载资源
问答
  • 使用Easy POI的API实现POI对Excel的所有操作,并且它的封装类可以让你快速上手,无需编写大量的Excel格式设置等复杂代码,高效,完善,高并发
  • Excel导出,js实现

    2018-12-27 15:45:28
    Excel导出,js实现.
  • excel导出可带图片

    2018-09-18 13:50:07
    可进行excel导出 支持图片的导出,亲自使用的整合到了一起
  • excel导出添加水印

    2018-08-02 17:31:31
    java通过POI组件可以给导出excel表格添加水印,不需要额外的组件
  • easypoi,Excel导出导出

    2016-12-29 15:07:19
    easypoi功能如同名字easy,主打的功能就是容易,让一个没见接触过poi的人员 就可以方便的写出Excel导出,Excel模板导出,Excel导入,Word模板导出,通过简单的注解和模板 语言(熟悉的表达式语法),完成以前复杂的写法
  • Freemarker实现excel导出功能,有例子
  • 直接可以用的项目。数据量大,导出多个excel然后压缩成zip文件。。。
  • javascript怎么导出多张工作表,并进行数据导入,可以兼容ie,firefox,google
  • thinkphp excel导出功能

    2014-08-26 14:17:21
    thinkphp excel导出功能 onethink也可以用
  • 改资源包含 数据量超过20万以上导出解决方案,还有动态获取数据公共类 1) 把数据分成多个sheet导出。 2) 把数据分成多个excel 导出。 全部都有,还有实例。
  • 基于POI+XML配置模板Excel导出

    热门讨论 2014-04-14 16:48:27
    基于POI+XML配置模板Excel导出,代码简单易用,模板与html类似,配置极易上手。支持单sheet和多sheet导出。支持导出样式及单元格融合,表头融合
  • Java之Excel导出工具类使用教程

    千次阅读 多人点赞 2019-03-20 17:34:02
    本工具类经过PostMan和...市面上有很多封装好的导出工具(如:阿里的easyExcel,GitHub上xxl-excel等),但如果直接引用依赖,扩展性和定制性比较差,所以博主通过apache.poi,自己实现一款Excel导出工具,方便定制使用。

    前言:

    本工具类经过PostMan和前端页面严格测试可用,经过了多个版本迭代优化,可以直接使用,也方便大家根据自己的业务需求,修改定制自己的导出工具。
    市面上有很多封装好的导出工具(如:阿里的easyExcel,GitHub上xxl-excel等),但如果直接引用依赖,扩展性和定制性比较差,所以博主通过apache.poi,自己实现一款Excel导出工具,方便定制使用。本工具类支持SpringMVC等主流的Java框架,支持RESTful接口,代码全部通过测试。

    一.功能介绍:

    • 支持多个Excel一次性导出并压缩成zip
    • 支持List<Entity>实体类导出
    • 支持List<Map>列数不固定的数据导出
    • 支持多Sheet页导出
    • 支持导出文件名为URLEncode,防止乱码
    • 支持文件名、sheet名特殊字符自动替换
    • 支持Excel2007以上版本
    • 支持有数据的文本框描边
    • 支持表头字体加大
    • 表头数据单元格内换行
    • 支持标题栏
    • 支持控制null空字段是否导出
    • 支持单元格将日期格式数据转换为自定义格式的时间字符串
    • 支持单元格类型区分数值、字符串,且单元格类型不同,单元格对齐方式不同。
    • 支持将Excel导出到HttpServletResponse流中(用做提供Api接口)

    二.导出工具类源码:

    注: 此工具类代码可直接在项目中使用。

    package com.xxx.util;
    import  com.xxx.util..ZipUtils;
    import lombok.extern.slf4j.Slf4j;
    import org.apache.commons.io.FileUtils;
    import org.apache.poi.ss.usermodel.BorderStyle;
    import org.apache.poi.ss.usermodel.HorizontalAlignment;
    import org.apache.poi.ss.util.CellRangeAddress;
    import org.apache.poi.xssf.usermodel.*;
    import org.springframework.util.ObjectUtils;
    
    import javax.servlet.ServletOutputStream;
    import javax.servlet.http.HttpServletResponse;
    import java.io.*;
    import java.lang.reflect.Field;
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    import java.net.URLEncoder;
    import java.text.SimpleDateFormat;
    import java.util.*;
    import java.util.regex.Matcher;
    import java.util.regex.Pattern;
    
    /**
     * 导出Excel工具类
     *
     * @author xuchao
     */
    @Slf4j
    public class ExportExcelUtil<T> {
    
    	// 新版Excel文件后缀
    	private static final String EXCEL_SUFFIX = ".xlsx";
    
    	/**
    	 * 导出多Sheet的Excel到HttpServletResponse流中(注:字段定义顺序需跟表头完全一致)
    	 *
    	 * (导出Excel格式:表头内容居中,字体略大于正文,颜色深灰色。正文文本类型对齐方式居左,数字类型对齐方式居右。仅有数据的单元格,有边框环绕,实体类的属性顺序即为表头顺序)
    	 *
    	 * @param fileName          Excel文件名
    	 * @param sheetNames        多个Sheet工作表的名称列表(不可重复)
    	 * @param titleList         多个Sheet的标题名称列表(没有标题,则传null)
    	 * @param headersList       多个Sheet的表头列表
    	 * @param dataLists         多个Sheet的数据源
    	 * @param response          Http响应
    	 * @param pattern           时间类型数据的格式,默认:yyyy-MM-dd HH:mm:ss
    	 * @param isExportNullField 空字段是否导出(true:导出,false:不导出)
    	 * @see ExportExcelUtilDemo 本方法使用示例
    	 */
    	public static <T> void exportExcel(String fileName, List<String> sheetNames, List<String> titleList,
    			List<List<String>> headersList, List<List<T>> dataLists, HttpServletResponse response, String pattern,
    			boolean isExportNullField) {
    		XSSFWorkbook wb = exportAllExcel(sheetNames, titleList, headersList, dataLists, pattern, isExportNullField);
    		setResponseHeader(response, replaceSpecialCharacter(fileName));
    		ServletOutputStream out = null;
    		try {
    			out = response.getOutputStream();
    			wb.write(out);
    		} catch (IOException e) {
    			e.printStackTrace();
    		} finally {
    			try {
    				out.flush();
    				out.close();
    				wb.close();
    			} catch (IOException e) {
    				e.printStackTrace();
    			}
    		}
    	}
    
    	/**
    	 * 导出多Sheet动态列的Excel到HttpServletResponse流中(注:字段定义顺序需跟表头完全一致)
    	 *
    	 * @param fileName          Excel文件名
    	 * @param sheetNames        多个Sheet工作表的名称列表(不可重复)
    	 * @param titleList         多个Sheet的标题名称列表(没有标题,则传null)
    	 * @param headersList       多个Sheet的表头列表
    	 * @param dataLists         多个Sheet的数据源
    	 * @param response          Http响应
    	 * @param pattern           时间类型数据的格式,默认:yyyy-MM-dd HH:mm:ss
    	 * @param isExportNullField 空字段是否导出(true:导出,false:不导出,导出空单元格显示为"--")
    	 */
    	public static void exportDynamicExcel(String fileName, List<String> sheetNames, List<String> titleList,
    			List<List<String>> headersList, List<List<Map<String, Object>>> dataLists, HttpServletResponse response,
    			String pattern, boolean isExportNullField) {
    		XSSFWorkbook wb = exportDynamicExcelImpl(sheetNames, titleList, headersList, dataLists, pattern,
    				isExportNullField);
    		setResponseHeader(response, replaceSpecialCharacter(fileName));
    		ServletOutputStream out = null;
    		try {
    			out = response.getOutputStream();
    			wb.write(out);
    		} catch (IOException e) {
    			e.printStackTrace();
    		} finally {
    			try {
    				out.flush();
    				out.close();
    				wb.close();
    			} catch (IOException e) {
    				e.printStackTrace();
    			}
    		}
    	}
    
    	/**
    	 * 导出多个Excel并压缩到zip包中
    	 *
    	 * @param response          HttpServletResponse
    	 * @param excelList         多个Excel数据源
    	 * @param filePath          导出路径(文件夹)
    	 * @param zipName           压缩包名,如(ABC)
    	 * @param pattern           Excel中的时间格式
    	 * @param isExportNullField 空字段是否导出(true:导出,false:不导出,导出空单元格显示为"--")
    	 */
    	public static void exportExcelsToZip(HttpServletResponse response, List<Map<String, Object>> excelList,
    			String filePath, String zipName, String pattern, boolean isExportNullField) {
    		setZipResponseHeader(response, replaceSpecialCharacter(zipName), true, ".zip");
    		long timestamp = System.nanoTime();
    		// 本次导出,生成一个excel文件的上级文件夹
    		String targetPath = filePath + File.separator + "temp" + File.separator + timestamp + File.separator + zipName;
    		for (Map<String, Object> excelMap : excelList) {
    			XSSFWorkbook wb = exportDynamicExcelImpl((List<String>) excelMap.get("sheetNames"), null,
    					(List<List<String>>) excelMap.get("headers"),
    					(List<List<Map<String, Object>>>) excelMap.get("dataLists"), pattern, isExportNullField);
    
    			// Excel输出路径示例:/usr/local/tomcat/excels/temp/1649149721911900/报表20210416/xx名称-20210416.xlsx
    			String excelPath =
    					targetPath + File.separator + replaceSpecialCharacter(excelMap.get("fileName").toString())
    							+ EXCEL_SUFFIX;
    			try {
    				File file = new File(excelPath);
    				FileUtils.forceMkdirParent(file);
    				FileOutputStream outputStream = new FileOutputStream(file);
    				wb.write(outputStream);
    				outputStream.close();
    				wb.close();
    				log.info("成功导出Excel:" + file.getName());
    			} catch (IOException e) {
    				log.warn("导出Excel时,创建文件出错");
    				e.printStackTrace();
    			} finally {
    				try {
    					wb.close();
    				} catch (IOException e) {
    					e.printStackTrace();
    				}
    			}
    		}
    		// 将所有Excel压缩,并写入到response中
    		ServletOutputStream out = null;
    		FileInputStream fileInputStream = null;
    		try {
    			// zip输出路径示例:/usr/local/tomcat/excels/temp/1649149721911900/日报20210416.zip
    			String outputPath =
    					filePath + File.separator + "temp" + File.separator + timestamp + File.separator + zipName
    							+ ZipUtils.ZIP_SUFFIX;
    			ZipUtils.compress(targetPath, outputPath);
    			File zipFile = new File(outputPath);
    			fileInputStream = new FileInputStream(zipFile);
    			BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);
    			out = response.getOutputStream();
    			byte[] bytes = new byte[bufferedInputStream.available()];
    			// 必须加此行代码,否则下载的Zip包损坏
    			int read = bufferedInputStream.read(bytes);
    			out.write(bytes);
    		} catch (IOException e) {
    			e.printStackTrace();
    		} finally {
    			try {
    				out.flush();
    				out.close();
    				fileInputStream.close();
    			} catch (IOException e) {
    				e.printStackTrace();
    			}
    		}
    	}
    
    	/**
    	 * 设置响应的类型、编码和文件名称
    	 *
    	 * @param response
    	 * @param fileName
    	 */
    	public static void setResponseHeader(HttpServletResponse response, String fileName) {
    		try {
    			response.reset();
    			response.setContentType("application/msexcel");// 设置生成的文件类型
    			response.setCharacterEncoding("UTF-8");// 设置文件头编码方式和文件名
    			// 在浏览器中测试生效,postman中文件名为response,无法修改
    			response.setHeader("Content-disposition", "attachment;filename=".concat(String
    					.valueOf(URLEncoder.encode(replaceSpecialCharacter(fileName) + EXCEL_SUFFIX, "UTF-8"))));
    			// 此设置,可保证web端可以取到文件名
    			response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
    			// 网关服务会校验是否有"Download"标识
    			response.setHeader("Response-Type", "Download");
    		} catch (Exception ex) {
    			ex.printStackTrace();
    		}
    	}
    
    	/**
    	 * 设置Zip下载的响应的类型、编码和文件名称
    	 *
    	 * @param response  http响应
    	 * @param fileName  文件名
    	 * @param urlEncode 是否URLEncode
    	 * @param zipSuffix zip后缀名(默认为.zip)
    	 */
    	public static void setZipResponseHeader(HttpServletResponse response, String fileName, boolean urlEncode,
    			String zipSuffix) {
    		try {
    			if (zipSuffix == null) {
    				zipSuffix = ".zip";
    			}
    			String downloadName = urlEncode == true ?
    					String.valueOf(URLEncoder.encode(replaceSpecialCharacter(fileName) + zipSuffix, "UTF-8")) :
    					String.valueOf(replaceSpecialCharacter(fileName) + zipSuffix);
    			response.reset();
    			// 设置生成的文件类型
    			response.setContentType("application/x-zip-compressed");
    			//response.setContentType("application/octet-stream");
    			// 设置文件头编码方式和文件名
    			response.setCharacterEncoding("UTF-8");
    			response.setHeader("Content-Disposition", "attachment;filename=".concat(downloadName));
    			response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
    			// 网关服务会校验是否有"Download"标识
    			response.setHeader("Response-Type", "Download");
    		} catch (Exception ex) {
    			ex.printStackTrace();
    		}
    	}
    
    	/**
    	 * 设置响应的类型、编码和文件名称
    	 *
    	 * @param response
    	 * @param fileName
    	 */
    	public static void setResponseHeader(HttpServletResponse response, String fileName, boolean urlEncode) {
    		try {
    			String downloadName = urlEncode == true ?
    					String.valueOf(URLEncoder.encode(replaceSpecialCharacter(fileName) + EXCEL_SUFFIX, "UTF-8")) :
    					String.valueOf(replaceSpecialCharacter(fileName) + EXCEL_SUFFIX);
    			response.reset();
    			response.setContentType("application/msexcel");// 设置生成的文件类型
    			response.setCharacterEncoding("UTF-8");// 设置文件头编码方式和文件名
    			// 在浏览器中测试生效,postman中文件名为response,无法修改
    			response.setHeader("Content-Disposition", "attachment;filename=".concat(downloadName));
    			response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
    			// 网关服务会校验是否有"Download"标识
    			response.setHeader("Response-Type", "Download");
    		} catch (Exception ex) {
    			ex.printStackTrace();
    		}
    	}
    
    	/**
    	 * 多Sheet导出实现
    	 *
    	 * @param sheetNames        Sheet页名称列表
    	 * @param titleList         标题列表
    	 * @param headersList       表头列表
    	 * @param dataLists         sheet数据源列表
    	 * @param pattern           时间格式
    	 * @param isExportNullField 是否导出空字段
    	 * @return
    	 */
    	private static <T> XSSFWorkbook exportAllExcel(List<String> sheetNames, List<String> titleList,
    			List<List<String>> headersList, List<List<T>> dataLists, String pattern, boolean isExportNullField) {
    		// 创建一个工作薄
    		XSSFWorkbook workbook = new XSSFWorkbook();
    		for (int i = 0; i < dataLists.size(); i++) {
    			// 创建一个工作表
    			XSSFSheet sheet = workbook.createSheet(replaceSpecialCharacter(sheetNames.get(i)));
    			// 设置单元格列宽度为16个字节
    			sheet.setDefaultColumnWidth((short) 16);
    			// 创建表头样式
    			XSSFCellStyle headersStyle = workbook.createCellStyle();
    			headersStyle.setBorderTop(BorderStyle.THIN);
    			headersStyle.setBorderBottom(BorderStyle.THIN);
    			headersStyle.setBorderLeft(BorderStyle.THIN);
    			headersStyle.setBorderRight(BorderStyle.THIN);
    			// 表头内容对齐方式:居中
    			headersStyle.setAlignment(HorizontalAlignment.CENTER);
    			XSSFFont headersFont = workbook.createFont();
    			// 设置字体格式
    			headersFont.setColor(new XSSFColor(java.awt.Color.DARK_GRAY));
    			headersFont.setFontHeightInPoints((short) 14);
    			// 表头样式应用生效
    			headersStyle.setFont(headersFont);
    			XSSFCellStyle dataSetStyle = workbook.createCellStyle();
    			// 正文单元格边框样式
    			dataSetStyle.setBorderBottom(BorderStyle.THIN);
    			dataSetStyle.setBorderRight(BorderStyle.THIN);
    			dataSetStyle.setBorderLeft(BorderStyle.THIN);
    			// 数据内容对齐方式:居左
    			// dataSetStyle.setAlignment(HorizontalAlignment.CENTER_SELECTION);
    			XSSFFont dataSetFont = workbook.createFont();
    			// 正文字体颜色
    			dataSetFont.setColor(new XSSFColor(java.awt.Color.BLACK));
    			// 为正文设置样式
    			dataSetStyle.setFont(dataSetFont);
    			// 获取当前Sheet页的表头
    			List<String> headers = headersList.get(i);
    			int index = 0;
    			if (!ObjectUtils.isEmpty(titleList)) {
    				String titleName = titleList.get(i);
    				if (!ObjectUtils.isEmpty(titleName)) {
    					XSSFCellStyle titleStyle = workbook.createCellStyle();
    					// 将首行合并居中作为标题栏
    					sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, headers.size() - 1));
    					XSSFFont titleFont = workbook.createFont();
    					// 设置标题字体大小
    					titleFont.setFontHeightInPoints((short) 20);
    					// 设置标题字体样式
    					titleStyle.setFont(titleFont);
    					// 创建标题行并设置样式
    					XSSFRow titleRow = sheet.createRow(0);
    					XSSFCell titleCell = titleRow.createCell(0);
    					titleCell.setCellStyle(titleStyle);
    					titleCell.setCellValue(titleName);
    					index = 1;
    				}
    			}
    			// 创建表头并设置样式
    			XSSFRow row = sheet.createRow(index);
    			for (short j = 0; j < headers.size(); j++) {
    				XSSFCell cell = row.createCell(j);
    				cell.setCellStyle(headersStyle);
    				XSSFRichTextString text = new XSSFRichTextString(headers.get(j));
    				cell.setCellValue(text);
    			}
    			// 导出正文数据,并设置其样式
    			Iterator<?> it = dataLists.get(i).iterator();
    			while (it.hasNext()) {
    				index++;
    				row = sheet.createRow(index);
    				Object entity = it.next();
    				// 利用反射,根据实体类属性的先后顺序,动态调用其getXxx()方法,得到属性值
    				Field[] fields = entity.getClass().getDeclaredFields();
    				for (short k = 0; k < fields.length; k++) {
    					XSSFCell cell = row.createCell(k);
    					Field field = fields[k];
    					String fieldName = field.getName();
    					String getMethodName = "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
    					try {
    						@SuppressWarnings("rawtypes")
    						Class entityClass = entity.getClass();
    						@SuppressWarnings("unchecked")
    						Method getMethod = entityClass.getMethod(getMethodName, new Class[] {});
    						Object value = getMethod.invoke(entity, new Object[] {});
    						String textValue = null;
    						// 如果是时间类型,格式化
    						if (value instanceof Date) {
    							Date date = (Date) value;
    							pattern = pattern == null || pattern.equals("") ? "yyyy-MM-dd HH:mm:ss" : pattern;
    							SimpleDateFormat sdf = new SimpleDateFormat(pattern);
    							textValue = sdf.format(date);
    						} else {
    							// 若字段为空且允许导出空字段,则将null导出为""
    							textValue = value == null && isExportNullField ? "" : value.toString();
    						}
    						if (!textValue.equals("")) {
    							// 有数据时边框环绕
    							cell.setCellStyle(dataSetStyle);
    							// 正则判断是否为数值
    							Pattern p = Pattern.compile("^\\d+(\\.\\d+)?$");
    							Matcher matcher = p.matcher(textValue);
    							if (matcher.matches()) {
    								// 是数字当作double处理,整型也不会补充小数点
    								cell.setCellValue(Double.parseDouble(textValue));
    							} else {
    								// 不是数字类型作为文本输出
    								cell.setCellValue(textValue);
    							}
    						}
    					} catch (SecurityException | NoSuchMethodException | IllegalArgumentException | IllegalAccessException | InvocationTargetException e) {
    						e.printStackTrace();
    					}
    				}
    			}
    		}
    		return workbook;
    	}
    
    	/**
    	 * 多Sheet导出动态列到Excel实现(数据源为Map)
    	 *
    	 * @param sheetNames        Sheet页名称列表
    	 * @param titleList         标题列表
    	 * @param headersList       表头列表
    	 * @param dataLists         sheet数据源列表
    	 * @param pattern           时间格式
    	 * @param isExportNullField 是否导出空字段
    	 * @return XSSFWorkbook workbook
    	 */
    	private static XSSFWorkbook exportDynamicExcelImpl(List<String> sheetNames, List<String> titleList,
    			List<List<String>> headersList, List<List<Map<String, Object>>> dataLists, String pattern,
    			boolean isExportNullField) {
    		// 创建一个工作薄
    		XSSFWorkbook workbook = new XSSFWorkbook();
    		for (int i = 0; i < dataLists.size(); i++) {
    			// 创建一个工作表
    			XSSFSheet sheet = workbook.createSheet(replaceSpecialCharacter(sheetNames.get(i)));
    			// 设置单元格列宽度为16个字节
    			sheet.setDefaultColumnWidth((short) 16);
    			// 创建表头样式
    			XSSFCellStyle headersStyle = workbook.createCellStyle();
    			headersStyle.setBorderTop(BorderStyle.THIN);
    			headersStyle.setBorderBottom(BorderStyle.THIN);
    			headersStyle.setBorderLeft(BorderStyle.THIN);
    			headersStyle.setBorderRight(BorderStyle.THIN);
    			// 表头内容对齐方式:居中
    			headersStyle.setAlignment(HorizontalAlignment.CENTER);
    			XSSFFont headersFont = workbook.createFont();
    			// 设置字体格式
    			headersFont.setColor(new XSSFColor(java.awt.Color.DARK_GRAY, new DefaultIndexedColorMap()));
    			headersFont.setFontHeightInPoints((short) 12);
    			// 表头样式应用生效
    			headersStyle.setFont(headersFont);
    			// 设置单元格内内容换行
    			headersStyle.setWrapText(true);
    			XSSFCellStyle dataSetStyle = workbook.createCellStyle();
    			// 正文单元格边框样式
    			dataSetStyle.setBorderBottom(BorderStyle.THIN);
    			dataSetStyle.setBorderRight(BorderStyle.THIN);
    			dataSetStyle.setBorderLeft(BorderStyle.THIN);
    			// 数据内容对齐方式:居左
    			// dataSetStyle.setAlignment(HorizontalAlignment.CENTER_SELECTION);
    			XSSFFont dataSetFont = workbook.createFont();
    			// 正文字体颜色
    			dataSetFont.setColor(new XSSFColor(java.awt.Color.BLACK, new DefaultIndexedColorMap()));
    			// 为正文设置样式
    			dataSetStyle.setFont(dataSetFont);
    			// 获取当前Sheet页的表头
    			List<String> headers = headersList.get(i);
    			int index = 0;
    			if (!ObjectUtils.isEmpty(titleList)) {
    				String titleName = titleList.get(i);
    				if (!ObjectUtils.isEmpty(titleName)) {
    					XSSFCellStyle titleStyle = workbook.createCellStyle();
    					// 将首行合并居中作为标题栏
    					sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, headers.size() - 1));
    					XSSFFont titleFont = workbook.createFont();
    					// 设置标题字体大小
    					titleFont.setFontHeightInPoints((short) 20);
    					// 设置标题字体样式
    					titleStyle.setFont(titleFont);
    					// 创建标题行并设置样式
    					XSSFRow titleRow = sheet.createRow(0);
    					XSSFCell titleCell = titleRow.createCell(0);
    					titleCell.setCellStyle(titleStyle);
    					titleCell.setCellValue(titleName);
    					index = 1;
    				}
    			}
    			// 创建表头并设置样式
    			XSSFRow row = sheet.createRow(index);
    			for (short j = 0; j < headers.size(); j++) {
    				XSSFCell cell = row.createCell(j);
    				cell.setCellStyle(headersStyle);
    				XSSFRichTextString text = new XSSFRichTextString(headers.get(j));
    				cell.setCellValue(text);
    			}
    			// 导出正文数据,并设置其样式
    			ListIterator<Map<String, Object>> it = dataLists.get(i).listIterator();
    			while (it.hasNext()) {
    				try {
    					index++;
    					row = sheet.createRow(index);
    					Map<String, Object> map = it.next();
    					headers = new ArrayList<String>(map.keySet());
    					List<Object> values = new ArrayList<Object>(map.values());
    					for (int k = 0; k < map.keySet().size(); k++) {
    						try {
    							XSSFCell cell = row.createCell(k);
    							cell.setCellStyle(dataSetStyle);
    							String textValue = null;
    							Object value = values.get(k);
    							// 如果是时间类型,格式化
    							if (value instanceof Date) {
    								Date date = (Date) value;
    								pattern = pattern == null || pattern.equals("") ? "yyyy-MM-dd HH:mm:ss" : pattern;
    								SimpleDateFormat sdf = new SimpleDateFormat(pattern);
    								textValue = sdf.format(date);
    							} else {
    								// 若字段为空且用户允许导出空字段,则将null导出为"--"
    								textValue = value == null && isExportNullField ? "--" : value.toString();
    							}
    							if (!textValue.equals("")) {
    								// 有数据时边框环绕
    								//cell.setCellStyle(dataSetStyle);
    								// 正则判断是否为数值
    								Pattern p = Pattern.compile("^\\d+(\\.\\d+)?$");
    								Matcher matcher = p.matcher(textValue);
    								if (matcher.matches()) {
    									// 是数字当作double处理,整型也不会补充小数点
    									cell.setCellValue(Double.parseDouble(textValue));
    								} else {
    									// 不是数字类型作为文本输出
    									cell.setCellValue(textValue);
    								}
    							}
    						} catch (Exception e) {
    							e.printStackTrace();
    						}
    					}
    				} catch (Exception e) {
    					e.printStackTrace();
    				}
    			}
    		}
    		return workbook;
    
    	}
    
    	/**
    	 * 用下划线替换所有特殊字符
    	 *
    	 * @param targetStr 目标字符串
    	 */
    	public static String replaceSpecialCharacter(String targetStr) {
    		if (null != targetStr && !"".equals(targetStr.trim())) {
    			String regEx = "[\\\\|:/\"<>?*\\[\\] ]";
    			Pattern p = Pattern.compile(regEx);
    			Matcher m = p.matcher(targetStr);
    			return m.replaceAll("_");
    		}
    		return null;
    	}
    
    }
    
    
    

    压缩工具类:

    注: 如果不需要导出后,将Excel压缩成Zip包功能,可以不导出此类。

    package com.xxx.util;
    
    /**
     * @description: 压缩工具类
     * @author: 大脑补丁
     * @create: 2021-04-16 15:51
     */
    
    import java.io.*;
    import java.util.Enumeration;
    import java.util.zip.*;
    
    public class ZipUtils {
    	static final int BUFFER = 8192;
    	static final String ZIP_SUFFIX = ".zip";
    
    	/**
    	 * 压缩文件
    	 *
    	 * @param srcPath 要压缩的文件或文件夹(如:/usr/local/目录)
    	 * @param zipPath 输出的zip文件路径(如:/usr/local/abc.zip)
    	 * @throws IOException
    	 */
    	public static void compress(String srcPath, String zipPath) throws IOException {
    		File srcFile = new File(srcPath);
    		File zipFile = new File(zipPath);
    		if (!srcFile.exists()) {
    			throw new FileNotFoundException(srcPath + "不存在!");
    		}
    		FileOutputStream out = null;
    		ZipOutputStream zipOut = null;
    		try {
    			out = new FileOutputStream(zipFile);
    			CheckedOutputStream cos = new CheckedOutputStream(out, new CRC32());
    			zipOut = new ZipOutputStream(cos);
    			String baseDir = "";
    			compress(srcFile, zipOut, baseDir);
    		} finally {
    			if (null != zipOut) {
    				zipOut.close();
    				out = null;
    			}
    
    			if (null != out) {
    				out.close();
    			}
    		}
    	}
    
    	private static void compress(File file, ZipOutputStream zipOut, String baseDir) throws IOException {
    		if (file.isDirectory()) {
    			compressDirectory(file, zipOut, baseDir);
    		} else {
    			compressFile(file, zipOut, baseDir);
    		}
    	}
    
    	/** 压缩一个目录 */
    	private static void compressDirectory(File directory, ZipOutputStream zipOut, String baseDir) throws IOException {
    		File[] files = directory.listFiles();
    		for (int i = 0; i < files.length; i++) {
    			compress(files[i], zipOut, baseDir + directory.getName() + "/");
    		}
    	}
    
    	/** 压缩一个文件 */
    	private static void compressFile(File file, ZipOutputStream zipOut, String baseDir) throws IOException {
    		if (!file.exists()) {
    			return;
    		}
    
    		BufferedInputStream bis = null;
    		try {
    			bis = new BufferedInputStream(new FileInputStream(file));
    			ZipEntry entry = new ZipEntry(baseDir + file.getName());
    			zipOut.putNextEntry(entry);
    			int count;
    			byte data[] = new byte[BUFFER];
    			while ((count = bis.read(data, 0, BUFFER)) != -1) {
    				zipOut.write(data, 0, count);
    			}
    
    		} finally {
    			if (null != bis) {
    				bis.close();
    			}
    		}
    	}
    
    	/**
    	 * 解压文件
    	 *
    	 * @param zipFile
    	 * @param dstPath
    	 * @throws IOException
    	 */
    	public static void decompress(String zipFile, String dstPath) throws IOException {
    		File pathFile = new File(dstPath);
    		if (!pathFile.exists()) {
    			pathFile.mkdirs();
    		}
    		ZipFile zip = new ZipFile(zipFile);
    		for (Enumeration entries = zip.entries(); entries.hasMoreElements(); ) {
    			ZipEntry entry = (ZipEntry) entries.nextElement();
    			String zipEntryName = entry.getName();
    			InputStream in = null;
    			OutputStream out = null;
    			try {
    				in = zip.getInputStream(entry);
    				String outPath = (dstPath + "/" + zipEntryName).replaceAll("\\*", "/");
    				;
    				//判断路径是否存在,不存在则创建文件路径
    				File file = new File(outPath.substring(0, outPath.lastIndexOf('/')));
    				if (!file.exists()) {
    					file.mkdirs();
    				}
    				//判断文件全路径是否为文件夹,如果是上面已经上传,不需要解压
    				if (new File(outPath).isDirectory()) {
    					continue;
    				}
    
    				out = new FileOutputStream(outPath);
    				byte[] buf1 = new byte[1024];
    				int len;
    				while ((len = in.read(buf1)) > 0) {
    					out.write(buf1, 0, len);
    				}
    			} finally {
    				if (null != in) {
    					in.close();
    				}
    
    				if (null != out) {
    					out.close();
    				}
    			}
    		}
    		zip.close();
    	}
    
    	public static void main(String[] args) throws Exception {
    		String targetFolderPath = "/Users/test/zipFile/zipFolder";
    		String rawZipFilePath = "/Users/test/zipFile/raw.zip";
    		String newZipFilePath = "/Users/test/zipFile/new.zip";
    
    		//将Zip文件解压缩到目标目录
    		decompress(rawZipFilePath, targetFolderPath);
    
    		//将目标目录的文件压缩成Zip文件
    		compress(targetFolderPath, newZipFilePath);
    
    	}
    }
    
    
    

    所需jar包依赖org.apache.poi版本:

     <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>4.1.0</version>
     </dependency>
    <dependency>
                <groupId>org.apache.poi</groupId>
                <artifactId>poi-ooxml</artifactId>
                <version>4.1.0</version>
                <exclusions>
                    <exclusion>
                        <artifactId>poi</artifactId>
                        <groupId>org.apache.poi</groupId>
                    </exclusion>
                    <exclusion>
                        <artifactId>xmlbeans</artifactId>
                        <groupId>org.apache.xmlbeans</groupId>
                    </exclusion>
                </exclusions>
     </dependency>
     <dependency>
                <groupId>org.apache.poi</groupId>
                <artifactId>poi-ooxml-schemas</artifactId>
                <version>4.1.2</version>
     </dependency>
    

    三.数据源数据结构解释:

    1.导出方法参数数据源:List<List<T>> dataLists

    第一层List:多个sheet页。
    第二层List:一个Sheet页下的多条数据。
    T:实体类,对应一个Sheet页下的一行数据。

    2.导出方法参数数据源:List<List<Map<String, Object>>> dataLists

    第一层List:多个Sheet页数据。
    第二层List:一个Sheet页下的多条数据
    Map<String, Object>:一个Sheet页下的一行数据,其中key:表头,value:对应单元格的值。

    四.功能和使用方法:

    1.导出实体类方式

    使用场景: 适合Excel列的名称顺序和列数是固定的业务场景。

    注意事项: 实体类的属性声明的顺序,即为Excel导出后列的顺序,想调整列的顺序,需调整实体类属性声明的顺序即可。

    导出方法:

    /**
    	 * 导出多Sheet的Excel到HttpServletResponse流中
    	 *
    	 * @param fileName
    	 *            另存为文件名
    	 * @param sheetName
    	 *            工作簿中的多张Sheet工作表的名称列表
    	 * @param titleName
    	 *            表格的标题名称(没有标题,则传null)
    	 * @param headers
    	 *            表头列表
    	 * @param dataList
    	 *            要导出的数据源
    	 * @param HttpServletResponse
    	 *            Http响应
    	 * @param pattern
    	 *            时间类型数据的格式,默认UTC格式
    	 * @param isExportNullField
    	 *            空字段是否导出(true:导出,false:不导出)
    	 */
    	public static <T> void exportExcel(String fileName, List<String> sheetNames, String titleName, List<String> headers,
    			List<List<T>> dataLists, HttpServletResponse response, String pattern, boolean isExportNullField){……}
    

    使用示例:

    实体类示例:

    // Excel对应实体类(字段定义顺序,必须和表头顺序一致)
    	@Data
    	public class AlarmEventDTO implements Serializable {
    		// 设备类型
    		private String deviceTypeName;
    		// 设备型号
    		private String deviceModeName;
    		// 测点编号
    		private String pointCode;
    		// 告警参数
    		private int warningCheckRule;
    		// 告警描述
    		private String warningCheckDesc;
    		// 告警级别
    		private Integer warningLevel;
    		// 告警类别
    		private String warningType;
    		// 是否启用
    		private String warningEnabled;
    		// 所属部件
    		private String belongComponent;
    
    	}
    
    

    注: 文件名和sheet名:注意不要含有Excel不支持的特殊字符。

    使用示例:
    在SpringMVC的RESTful接口中,控制器中调用示例

    /**
    	 * Controller层使用示例
    	 */
    	//@GetMapping(value = "/alarm/export")
    	public void exportAlarmEvent(HttpServletResponse response) {
    		// 调用你的服务,获取数据源
    		List<List<AlarmEventDTO>> dataLists = new ArrayList<>();
    
    		if (dataLists != null && dataLists.size() > 0) {
    			try {
    				// Sheet页名称列表
    				List<String> sheetNames = new ArrayList<String>();
    				// 一个Sheet页表头名称列表
    				List<String> headers = new ArrayList<String>(
    						Arrays.asList("设备类型", "设备型号", "测点编号", "告警参数", "告警描述", "告警级别", "告警类别", "是否启用", "所属部件"));
    				// 模拟多个Sheet页表头
    				List<List<String>> headersList = Arrays.asList(headers, headers, headers);
    				// 多个Sheet页标题列表(若)
    				List<String> titleList = new ArrayList<String>();
    				ExportExcelUtil
    						.exportExcel("Excel文件名", sheetNames, titleList, headersList, dataLists, response, null, true);
    			} catch (Exception e) {
    				log.error("导出告警事件出错", e);
    			}
    		}
    	}
    

    2.导出Map对象的方式

    使用场景: 适合Excel列的名称和顺序和列数是不固定的,如每次导出的列数可能不一致的场景。

    注意事项: Excel导出后列的顺序,为Map中的键值对加入的顺序,要想导出后列的顺序固定,可将Map实例化为LinkedHashMap即可使导出后的列顺序不会改变。

    例: 如下方式缓存导出数据,导出后的“名称”列,会在“类型”列的左侧。

    Map<String, Object> tempMap = new LinkedHashMap<String, Object>();
        tempMap.put("名称", device.getName());
    	tempMap.put("类型", device.getDeviceType());
    

    导出方法:

    /**
    	 * 导出多Sheet动态列的Excel到HttpServletResponse流中
    	 *
    	 * @param fileName          另存为文件名
    	 * @param sheetNames        工作簿中的多张Sheet工作表的名称列表
    	 * @param titleName         表格的标题名称(没有标题,则传null)
    	 * @param headersList       多个sheet页的表头列表
    	 * @param dataLists         要导出的数据源
    	 * @param response          Http响应
    	 * @param pattern           时间类型数据的格式,默认UTC格式
    	 * @param isExportNullField 空字段是否导出(true:导出,false:不导出)
    	 */
    	public static void exportDynamicExcel(String fileName, List<String> sheetNames, String titleName,
    			List<List<String>> headersList, List<List<Map<String, Object>>> dataLists, HttpServletResponse response,
    			String pattern, boolean isExportNullField) {……}
    

    使用示例:
    在SpringMVC的RESTful接口中,控制器中调用示例:

    @PostMapping(value = "/history/export")
    	public void exportHistory(HttpServletResponse response, @RequestBody Params params) {
    		List<List<Map<String, Object>>> datalists = deviceService.exportHistory(params);
    		if (!datalists.isEmpty()) {
    			try {
    				List<String> headers1 = new ArrayList<String>("表头列名1","表头列名2","表头列名3");
    				List<String> headers2 = new ArrayList<String>("表头列名1","表头列名2","表头列名3");
    				String fileName ="你的文件名,若包含Excel不支持的特殊字符,会自动处理成下划线";
    				ExportExcelUtil.exportDynamicExcel(fileName, Arrays.asList("用户历史数据"), null, Arrays.asList(headers1 ,headers2), datalists, response,
    						null, true);
    			} catch (Exception e) {
    				e.printStackTrace();
    			}
    		}
    	}
    

    3.多个Excel同时导出并压缩成zip包示例

    ①:Seivice层组装数据源

    看清楚数据结构的嵌套,组装好数据源。这里展示两个Excel同时导出的数据源结构。

    public class YourService{
    
    public List<Map<String, Object>>  export (ExcelInput input){
    
    		// 多个Excel的数据源
    		List<Map<String, Object>> resultList = new ArrayList<>();
    		
    		// 多个Sheet页数据源,每个List<Map<String, Object>>为一个Sheet页的数据源
    		List<List<Map<String, Object>>> deviceDataLists = new LinkedList<>();
    		// 第1个Excel数据源
    		Map<String, Object> powerExcelMap = new HashMap<>();
    		powerExcelMap.put("dataLists", deviceDataLists);
    		powerExcelMap.put("fileName", "excel文件名字1");
    		//多个Sheet页名字
    		powerExcelMap.put("sheetNames", Arrays.asList("第1个sheet页名字","第2个sheet页名字"));
    		// 第一个Sheet页的表头
    		List<String> powerHeaders1 = new LinkedList<>();
    		// 第二个Sheet页的表头
    		List<String> powerHeaders2 = new LinkedList<>();
    		powerExcelMap.put("headers", Arrays.asList(powerHeaders1,powerHeaders2 ));
    		resultList.add(powerExcelMap);
    
    		// 第2个Excel数据源
    		List<List<Map<String, Object>>> weatherDataLists= new LinkedList<>();
    		List<String> weatherHeaders = new LinkedList<>();
    		Map<String, Object> weatherExcelMap = new HashMap<>();
    		weatherExcelMap.put("dataLists", weatherDataLists);
    		weatherExcelMap.put("fileName",  "excel文件名字2");
    		powerExcelMap.put("sheetNames", Arrays.asList("第1个sheet页名字","第2个sheet页名字"));
    		// 第一个Sheet页的表头
    		List<String> weatherHeaders1 = new LinkedList<>();
    		// 第二个Sheet页的表头
    		List<String> weatherHeaders2 = new LinkedList<>();
    		weatherExcelMap.put("headers", Arrays.asList(weatherHeaders1,weatherHeaders2));
    		resultList.add(weatherExcelMap);
    	}
    }
    

    ②.Contorller层调用Excel工具类导出多个Excel到Response中

    @PostMapping("/export")
    public void export (HttpServletResponse response, @RequestBody ExcelInput input) {
    	// 获取①中的数据源
    	List<Map<String, Object>> excelList = yourService.export(input);
    	if (ObjectUtils.isEmpty(excelList) || ObjectUtils.isEmpty(input.getTime())) {
    		return;
    	}
    	// 导出多个Excel到zip包中
    	ExportExcelUtil.exportExcelsToZip(response, excelList, filePath,  "压缩包名称", null, true);
    }
    

    五.导出效果测试:

    1.PostMan测试:

    导出多个Excel到Zip包中示例:

    注意:文件名中的中文都经过URLEncode,需要请前端同学URLDecode一下,即可展示出中文名。
    在这里插入图片描述

    2.网页测试:

    3.导出效果图:

    看下导出的效果吧,边框、表头、对齐方式、字体大小、单元格数据换行、时间字符串格式转换等。效果满意的话点个赞吧!

    Excel实用教程集锦

    以下是我写的关于Java操作Excel的所有教程,基本包含了所有场景。

    1.如果简单导出推荐使用工具类的方式,这种配置最简单。

    2.如果对导出样式要求极高的还原度,推荐使用Freemarker方式,FreeMarker模板引擎可以通吃所有Excel的导出,属于一劳永逸的方式,项目经常导出推荐使用这种方式。

    3.Freemarker导出的Excel为xml格式,是通过重命名为xls后,每次会打开弹框问题,我在《Freemarker整合poi导出带有图片的Excel教程》也已经完美解决,本教程将直接导出真正的xls格式,完美适配新版office和wps。Freemarker是无法导出带有图片的Excel,通过其他技术手段,也在本教程中完美导出带有图片的Excel。

    4.下列教程中的代码都经本人和网友多次验证,真实有效!

    ↓↓↓↓一揽子Excel解决方案,赶快收藏吧↓↓↓↓

    《Java导入Excel工具类使用教程》

    《Java之Excel导出工具类使用教程》

    《Freemarker导出复杂Excel图文教程》

    《Freemarker整合poi导出带有图片的Excel教程》

    展开全文
  • PHP版Excel导出(实力很强悍的一种,无需插件,且可以保留模板格式)!
  • excel导出

    万次阅读 2018-11-06 10:57:14
    下面为本地生成excel的例子,若需导出,则将文件输出流转为response输出流。   package excel; import java.io.File; import java.io.FileOutputStream; import java.io.OutputStream; import jxl.Workbook; ...

    下面为本地生成excel的例子,若需导出,则将文件输出流转为response输出流。

     

    package excel;
    
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.OutputStream;
    
    import jxl.Workbook;
    import jxl.format.UnderlineStyle;
    import jxl.write.Colour;
    import jxl.write.Label;
    import jxl.write.WritableCellFormat;
    import jxl.write.WritableFont;
    import jxl.write.WritableSheet;
    import jxl.write.WritableWorkbook;
    
    public class WriteExcel {
    	
    	public void writeExcel() throws Exception{
    		File file = new File("D:\\Sim\\Project\\Excel\\test2.xls");
    		if (!file.exists()) {
    			file.createNewFile();
    		}
    		
    		OutputStream os = new FileOutputStream(file);// 取得输出流
    
    
            WritableWorkbook wbook = Workbook.createWorkbook(os); // 建立excel文件
            String tmptitle = "测试数据"; // 标题
            WritableSheet wsheet = wbook.createSheet(tmptitle, 0); // sheet名称
    
            // 设置excel标题
            WritableFont wfont = new WritableFont(WritableFont.ARIAL, 16, WritableFont.BOLD, false,
                                                  UnderlineStyle.NO_UNDERLINE, Colour.BLACK);
            WritableCellFormat wcfFC = new WritableCellFormat(wfont);
            wcfFC.setBackground(Colour.AQUA);
            wsheet.addCell(new Label(1, 0, tmptitle, wcfFC));
            wfont = new jxl.write.WritableFont(WritableFont.ARIAL, 14, WritableFont.BOLD, false,
                                               UnderlineStyle.NO_UNDERLINE, Colour.BLACK);
            wcfFC = new WritableCellFormat(wfont);
    
            // 开始生成主体内容
            wsheet.addCell(new Label(0, 2, "姓名"));
            wsheet.addCell(new Label(1, 2, "性别"));
            wsheet.addCell(new Label(2, 2, "证件类型"));
            wsheet.addCell(new Label(3, 2, "证件号码"));
            wsheet.addCell(new Label(4, 2, "手机号"));
           
            int count = 0;
            for (int i=0;i<10;i++) {
                wsheet.addCell(new Label(0, count + 3, "我是"+i+"号"));
                wsheet.addCell(new Label(4, count + 3, "my phone is:"+i));
                count++;
            }
    
            // 主体内容生成结束
            wbook.write();   // 写入文件
            wbook.close();
            os.close();   // 关闭流
    
    		
    	}
    	
    }
    

     

     

    pom依赖:

     

    <dependencies>
    		<dependency>
    			<groupId>org.apache.poi</groupId>
    			<artifactId>poi-ooxml</artifactId>
    			<version>3.9</version>
    		</dependency>
    		<!-- https://mvnrepository.com/artifact/net.sourceforge.jexcelapi/jxl -->
    		<dependency>
    			<groupId>net.sourceforge.jexcelapi</groupId>
    			<artifactId>jxl</artifactId>
    			<version>2.6</version>
    		</dependency>
    
    	</dependencies>

     

    结果图: 

     

     

    new Label(0, 2, "姓名")  指 新建一格 A3     相当于直角坐标系的X/Y轴定位

    x轴 数组对应关系为{0,1,2,3,.......,25} to  {A,B,C,........,Z}

    y轴 从也是从0开始

     

    展开全文
  • C#导出Excel 导出PDF

    热门讨论 2010-05-21 15:17:59
    C#程序将查询结果,表格等信息导出Excel或者导出PDF格式文档
  • 提到Excel导出功能,可能很多人都使用springmvc框架做过,笔者今天要给大家分享的是基于springBoot开发Excel复杂模板导出功能(所谓复杂模板指在模板里的特定表头里有不同的单元格合并以及背景色,字体颜色的填充,...

    提到Excel导出功能,可能很多人都使用springmvc框架做过,笔者今天要给大家分享的是基于springBoot开发Excel复杂模板导出功能(所谓复杂模板指在模板里的特定表头里有不同的单元格合并以及背景色,字体颜色的填充,文本内容的对齐方式等)。

    实现思路:

    首先在springBoot(或者SpringCloud)项目的默认templates目录放入提前定义好的Excel模板,然后在具体的导出接口业务代码里通过IO流加载到这个Excel模板文件,读取指定的工作薄(也就是excel左下角的Sheet),接着给模板里的指定表头填充表头数据,接着读取数据库的相关数据用数据传输模型(DTO)封装数据,最后循坏填充excel的数据行(逐行逐列的填充数据),最后把填充完数据的Excel文件流输出(下载),即完成了数据库数据按照指定Excel模板导出Excel的完整过程。废话不多说,下面直接上代码。

    一、配置POI框架的依赖

    本案例是maven项目,解析Excel采用市面主流的POI框架,在pom.xml文件添加POI框架的依赖

    <!--读取excel文件,配置POI框架的依赖-->
    <dependency>
    	<groupId>org.apache.poi</groupId>
    	<artifactId>poi</artifactId>
    	<version>3.17</version>
    </dependency>
    <dependency>
    	<groupId>org.apache.poi</groupId>
    	<artifactId>poi-ooxml</artifactId>
    	<version>3.17</version>
    </dependency>

    二、放入excel模板文件

    目录结构如下所示:

    二、导出excel具体实现

    @RestController
    @RequestMapping("/excel")
    public class ExcelExportController {
    
    	
      @RequestMapping(value="/excelExport")
      public ResponseEntity<Resource> excel2007Export(HttpServletResponse response,HttpServletRequest request) {
       try {
         ClassPathResource cpr = new ClassPathResource("/templates/"+"student.xlsx");
         InputStream is = cpr.getInputStream();
    	 Workbook workbook = new XSSFWorkbook(is);
    	 org.apache.poi.ss.usermodel.Sheet sheet0 =workbook.getSheetAt(0);
    	 Row row = sheet0.getRow(2);
    	 Cell cell0 = row.getCell(0);
    	 Cell cell1 = row.getCell(1);
    	 Cell cell2 = row.getCell(2);
    	 cell0.setCellValue("guo");
    	 cell1.setCellValue("bin");
    	 cell2.setCellValue("hui");
    	 System.out.println(cell0);
    	 //这里作为演示,造几个演示数据,模拟数据库里查数据
    	 List <Student> list =  new ArrayList<Student>();
    	Student st1 = new Student();
    	Student st2 = new Student();
    	st1.setName("张三");
    	st1.setScore("87");
    	st1.setClass("一班");
    	st2.setName("张四");
    	st2.setScore("57");
    	st2.setClass("二班");
    	list.add(st1);
    	list.add(st2);
    	for(int i = 0;i<list.size();i++){
    		Row row = sheet0.getRow(i+3);//从第三行开始填充数据
    		row.setCellValue(list.get(i).getName());
    		row.setCellValue(list.get(i).getScore());
    		row.setCellValue(list.get(i).getClass());
    	}
    	String fileName = "moban.xlsx";
    	downLoadExcel(fileName, response, workbook);
    			
    	} catch (FileNotFoundException e) {
    		// TODO Auto-generated catch block
    		e.printStackTrace();
    	} catch (IOException e) {
    		// TODO Auto-generated catch block
    		e.printStackTrace();
    	}
        return new ResponseEntity<Resource>(HttpStatus.OK);
    }
    	
    public static void downLoadExcel(String fileName, HttpServletResponse response, Workbook workbook) {
    	try {
    		response.setCharacterEncoding("UTF-8");
    		response.setHeader("content-Type", "application/vnd.ms-excel");
    		response.setHeader("Content-Disposition",
    					"attachment;filename=\"" + URLEncoder.encode(fileName, "UTF-8") + "\"");
    		workbook.write(response.getOutputStream());
    	} catch (IOException e) {
    		e.printStackTrace();
    	}
       }
    }

    欢迎各位开发者朋友一起交流。笔者电话(微信):18629374628

    展开全文
  • java实现数据的Excel导出, 自定义导出字段, 转换字典值 第一版代码: 基础功能跳转此文章java自定义Excel导出工具: 简介 新增功能: 添加自定义字段导出功能, 用户可以选择字段进行导出 将字典类型数据进行转换(如:0=...

    java实现数据的Excel导出, 自定义导出字段, 转换字典值

    第一版代码:
    基础功能跳转此文章java自定义Excel导出工具:

    简介

    新增功能:

    1. 添加自定义字段导出功能, 用户可以选择字段进行导出
    2. 将字典类型数据进行转换(如:0=女,1=男, 将0转换为女, 1转换为男)
    3. 添加表头格式
    4. 随机文件名称, 防止多次导出时文件覆盖问题
    实现代码

    Excel注解

    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.FIELD)
    public @interface Excel {
        /**
         * 导出到Excel中的名字
         */
        String name() default "";
    
        /**
         * 日期格式, 如: yyyy-MM-dd
         */
        String dateFormat() default "";
    
        /**
         * 字典的key值
         */
        String dictKey() default "";
    
        /**
         * 读取内容转表达式 (如: 0=男,1=女,2=未知)
         */
        String dictExp() default "";
    }
    
    

    Excel的导出工具类

    /**
     * Excel的工具类
     */
    public class ExcelUtil<T> {
    
        /**
         * 工作薄
         */
        private Workbook wb;
    
        /**
         * 工作表
         */
        private Sheet sheet;
    
        /**
         * 需要导出的数据
         */
        private List<T> exportList;
    
        /**
         * 对象的class对象
         */
        private Class<T> clazz;
    
        /**
         * 被选中需要导出的字段名称
         */
        private Map<String, Object> checkedFieldsName;
    
        /**
         * 被选中需要导出的字段对象
         */
        private List<Field> checkedFields;
    
        /**
         * 包含需要字典转换的字段对象
         */
        private List<Field> fieldsContainDict;
    
        /**
         * 对象中的字典值
         */
        private Map<String, Map<String, String>> dicts;
    
        private ExcelUtil(){
        }
    
        public ExcelUtil(Class<T> clazz){
            this.clazz = clazz;
        }
    
        /**
         *
         * @param list
         * @param sheetName
         * @param fieldsName
         */
        public void exportExcel(List<T> list, Map<String, Object> fieldsName, String sheetName){
            // 初始化数据
            init(list, sheetName, fieldsName);
    
            // 转换字典值
            try {
                convertDict();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
    
            // sheet第一行加入名称数据
            createTopRow();
    
            // sheet其他行,添加目标数据
            try {
                createOtherRow();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
    
            // 导出wb
            try(OutputStream outFile = new FileOutputStream(generateFileName())){
                wb.write(outFile);
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    wb.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    
        /**
         * 添加导出数据
         */
        private void createOtherRow() throws IllegalAccessException {
            for (int rowNum = 1; rowNum <= exportList.size(); rowNum++) {
                Row row = sheet.createRow(rowNum);
                T t = exportList.get(rowNum - 1);
    
                for (int colNum = 0; colNum < checkedFields.size(); colNum++) {
                    Cell cell = row.createCell(colNum);
                    Field field = checkedFields.get(colNum);
                    field.setAccessible(true);
    
                    // 单元格设置值
                    addCell(cell, field, t);
                }
            }
        }
    
        /**
         * 单元格中添加数据
         *
         * @param cell  单元格
         * @param field 字段
         * @param t     list中的一条数据
         */
        private void addCell(Cell cell, Field field, T t) throws IllegalAccessException {
            Class<?> fieldType = field.getType();
            if (String.class == fieldType) {
                cell.setCellValue((String) field.get(t));
            } else if ((Integer.TYPE == fieldType) || (Integer.class == fieldType)) {
                cell.setCellValue((Integer) field.get(t));
            } else if ((Long.TYPE == fieldType) || (Long.class == fieldType)) {
                cell.setCellValue((Long) field.get(t));
            } else if ((Double.TYPE == fieldType) || (Double.class == fieldType)) {
                cell.setCellValue((Double) field.get(t));
            } else if ((Float.TYPE == fieldType) || (Float.class == fieldType)) {
                cell.setCellValue((Float) field.get(t));
            } else if (Date.class == fieldType) {
                String dateFormat = field.getAnnotation(Excel.class).dateFormat();
                cell.setCellValue(dateFormat((Date) field.get(t), dateFormat));
            }
        }
    
        /**
         * 时间格式转换
         * @param date 日期
         * @param dateFormat 日期格式
         * @return
         */
        private String dateFormat(Date date, String dateFormat) {
            if (dateFormat == null || "".equals(dateFormat)) {
                dateFormat = "yyyy-MM-dd HH:mm:ss";
            }
    
            SimpleDateFormat df = new SimpleDateFormat(dateFormat);
            return df.format(date);
        }
    
        /**
         * sheet第一行加入名称数据
         */
        private void createTopRow() {
            Row row = sheet.createRow(0);
            Map<String, CellStyle> styles = createStyles(wb);
    
            for (int index = 0; index < checkedFields.size(); index++) {
                Cell cell = row.createCell(index);
                cell.setCellValue(checkedFields.get(index).getAnnotation(Excel.class).name());
                System.out.println(styles.get("header"));
                cell.setCellStyle(styles.get("header"));
            }
        }
    
        /**
         * 转换字典值
         *     将数据中字典值转化为对应的值(注:字典值应为String格式)
         */
        private void convertDict() throws IllegalAccessException {
            for (Field field : fieldsContainDict) {
                Excel annotation = field.getAnnotation(Excel.class);
                String dictKey = annotation.dictKey();
                field.setAccessible(true);
                for (T t : exportList) {
                    // 获取字段值
                    String o = (String) field.get(t);
                    field.set(t, dicts.get(dictKey).get(o));
                }
            }
        }
    
        /**
         * 将数据导出Excel
         *
         * @param list 需要导出的数据
         * @param sheetName 工作表名称
         */
        public void exportExcel(List<T> list, String sheetName){
            exportExcel(list, null, sheetName);
        }
    
        /**
         * 将数据导出Excel
         *
         * @param list 需要导出的数据
         */
        public void exportExcel(List<T> list) {
            exportExcel(list, null, "sheet");
        }
    
        /**
         * 初始化
         */
        public void init(List<T> list ,String sheetName,  Map<String, Object> fieldsName){
            this.checkedFieldsName = fieldsName;
    
            this.exportList = list;
    
            // 初始化导出数据
            initExportList();
    
            // 初始化工作薄
            initWorkbook();
    
            // 初始化工作表
            initSheet(sheetName);
    
            // 初始化checkedFields, fieldsContainDict
            initFields();
    
            // 根据注解生成生成字典
            generateObjDict();
        }
    
        /**
         * 初始化导出数据
         */
        private void initExportList(){
            // 防止导出过程中出现空指针
            if(Objects.isNull(this.exportList)) {
                this.exportList = new ArrayList<>();
            }
        }
    
        /**
         * 初始化工作簿
         */
        private void initWorkbook(){
            this.wb = new SXSSFWorkbook();
        }
    
        /**
         * 初始化工作表
         */
        private void initSheet(String sheetName){
            this.sheet = wb.createSheet(sheetName);
        }
    
        /**
         * 初始化checkedFields, fieldsContainDict
         *     fieldsContainDict含有字典表达式的字段
         *     checkedFields用户选中的字段
         *        1.如果checkedFieldsName没有定义(未自定义导出字段),所有字段全部导出
         *        2.如果checkedFieldsName进行了定义,根据定义字段进行导出
         */
        private void initFields(){
            // 获取对象所有字段对象
            Field[] fields = clazz.getDeclaredFields();
    
            // 过滤出checkedFields
            this.checkedFields = Arrays.
                    asList(fields).
                    stream().
                    filter(item -> {
                        if(!Objects.isNull(this.checkedFieldsName)) {
                            if (item.isAnnotationPresent(Excel.class)) {
                                return checkedFieldsName.containsKey(item.getName());
                            }
                        } else {
                            return item.isAnnotationPresent(Excel.class);
                        }
                        return false;
                    })
                    .collect(Collectors.toList());
    
            // 过滤出fieldsContainDict
            for (Field declaredField : clazz.getDeclaredFields()) {
                if(declaredField.getAnnotation(Excel.class) != null) {
                    System.out.println(declaredField.getAnnotation(Excel.class).dictExp());
                }
            }
            this.fieldsContainDict = Arrays
                    .asList(clazz.getDeclaredFields())
                    .stream()
                    .filter(item -> !"".equals(item.getAnnotation(Excel.class) != null? item.getAnnotation(Excel.class).dictExp() : ""))
                    .collect(Collectors.toList());
        }
    
        /**
         * 通过扫描字段注解生成字典数据
         */
        private void generateObjDict(){
            if(fieldsContainDict.size() == 0) {
                return;
            }
    
            if(dicts == null) {
                dicts = new HashMap<>(); //  Map<String, List<Map<String, String>>>
            }
    
            for (Field field : fieldsContainDict) {
                String dictKey = field.getAnnotation(Excel.class).dictKey();
                String exps = field.getAnnotation(Excel.class).dictExp();
                String[] exp = exps.split(",");
    
                Map<String, String> keyV = new HashMap<>();
    
                dicts.put(dictKey, keyV);
    
                for (String s : exp) {
                    String[] out = s.split("=");
                    keyV.put(out[0], out[1]);
                }
    
                System.out.println("字典值:"+ dicts);
            }
        }
    
        /**
         * 创建表格样式
         *
         * @param wb 工作薄对象
         * @return 样式列表
         */
        private Map<String, CellStyle> createStyles(Workbook wb)
        {
            Map<String, CellStyle> styles = new HashMap<String, CellStyle>();
            // 数据格式
            CellStyle style = wb.createCellStyle();
            style.setAlignment(HorizontalAlignment.CENTER);
            style.setVerticalAlignment(VerticalAlignment.CENTER);
            style.setBorderRight(BorderStyle.THIN);
            style.setRightBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
            style.setBorderLeft(BorderStyle.THIN);
            style.setLeftBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
            style.setBorderTop(BorderStyle.THIN);
            style.setTopBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
            style.setBorderBottom(BorderStyle.THIN);
            style.setBottomBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
            Font dataFont = wb.createFont();
            dataFont.setFontName("Arial");
            dataFont.setFontHeightInPoints((short) 10);
            style.setFont(dataFont);
            styles.put("data", style);
    
            // 表头格式
            style = wb.createCellStyle();
            style.cloneStyleFrom(styles.get("data"));
            style.setAlignment(HorizontalAlignment.CENTER);
            style.setVerticalAlignment(VerticalAlignment.CENTER);
            style.setFillForegroundColor(IndexedColors.GREY_50_PERCENT.getIndex());
            style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
            Font headerFont = wb.createFont();
            headerFont.setFontName("Arial");
            headerFont.setFontHeightInPoints((short) 10);
            headerFont.setBold(true);
            headerFont.setColor(IndexedColors.WHITE.getIndex());
            style.setFont(headerFont);
            styles.put("header", style);
    
            return styles;
        }
    
        /**
         * 生成随机名称,防止文件复写
         * @return
         */
        private String generateFileName(){
            return "D:\\" + UUID.randomUUID().toString().replace("-", "") + ".xlsx";
        }
    }
    
    
    使用方法

    将对象加上工具类需要的注解:

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public class Student {
    
        @Excel(name = "姓名")
        private String name;
    
        @Excel(name = "年龄")
        private Integer age;
    
        @Excel(name = "出生日期", dateFormat = "yyyy-MM-dd")
        private Date birthday;
    
        @Excel(name = "性别", dictKey = "sex", dictExp = "1=男,2=女")
        private String sex;
    }
    

    测试字典转换

    public static void main(String[] args) {
        ArrayList<Student> data = new ArrayList<>();
        Student student = new Student();
        student.setName("tom");
        student.setAge(19);
        student.setSex("1");
        student.setBirthday(new Date());
        data.add(student);
    
        ExcelUtil<Student> util = new ExcelUtil<>(Student.class);
        util.exportExcel(data, "人员信息表");
    }
    

    输出结果:

    在这里插入图片描述
    结果可以看出, 已将1转换为


    测试选择字段导出:
    若不自定义导出的字段, 工具将会把所有带有Excel注解的字段进行导出, 如上方所示。
    当输入导出字段时,才能根据定义的字段进行导出,实现如下:

    public static void main(String[] args) {
        ArrayList<Student> data = new ArrayList<>();
        Student student = new Student();
        student.setName("tom");
        student.setAge(19);
        student.setSex("1");
        student.setBirthday(new Date());
        data.add(student);
    
        // 需要导出字段的名称,放入map的key中即可(这里只导出姓名和性别)
        Map<String, Object> fieldsName = new HashMap<>();
        fieldsName.put("name", null);
        fieldsName.put("sex", null);
    
        ExcelUtil<Student> util = new ExcelUtil<>(Student.class);
        // 将fieldsName放入方法中
        util.exportExcel(data, fieldsName,"人员信息表");
    }
    

    在这里插入图片描述

    展开全文
  • 具体思路是:后端返回给我json数据,前端根据数据和具体的几项字段去导出excel表格,还有导出多个sheet,多页表格到一个excel表里面,具体思路 根据Export2Excel插件,并修改插件Export2Excel完成导出多页(多个sheet...
  • Springboot 使用easyexcel 实现Excel导出 导入easyexcel依赖 <!--alibaba easyexcel excel导出依赖--> <dependency> <groupId>com.alibaba</groupId> <artifactId>easyexcel</...
  • java:用HSSFWorkbook实现excel导出

    千次阅读 2020-03-19 22:34:51
    业务:选定需导出的档案字段,然后导出。 数据库档案字段值表为:信息用户id-档案字段id-档案字段值 已有获取档案信息方法:getFieldValueList(List< Integer> cardFieldIds, Integer userId),传入需导出的...
  • ThingsBoard CE添加Excel导出功能-优化篇

    千次阅读 2021-04-19 10:43:31
    如何添加Excel导出功能请跳转上一篇ThingsBoard CE数据导出excel,这篇做优化. 按照ThingsBoard CE数据导出excel的步骤做完,所有部件类型都加上了数据导出功能。实际上rpc,alarm,static是不需要的。 小部件有五...
  • //导出数据量超出excel最大承载量时 每个sheet最多多少行,此处从配置文件中获取此值 int maxCount = int.Parse(ConfigurationManager.AppSettings["MaxCount"]); int index = 0;//索引批次 var result = new ...
  • easyPoi导出excel导出错误

    千次阅读 2019-11-22 14:46:33
    easyPoi导出excel导出错误解决方案 最近项目中忽然出现excel不能导出的错误,以前测试是好用的,跟代码发现是在默认样式时报控制针问题,此问题为poi依赖缺少或者easypoi版本太低导致,项目中使用的为3.0.1版本,又...
  • js-table2excel 导出带图片的excel

    千次阅读 热门讨论 2020-06-10 17:19:43
    第二步引入:在需要导出表格的页面引入 import table2excel from 'js-table2excel' 第三步使用 : <template> <el-button type="primary" @click="exportExcel">导出EXCEL</el-button> </...
  • post请求实现excel导出下载功能

    万次阅读 2019-05-17 21:58:09
    { "fileName" : "riemann的Excel导出功能测试", "templateType":0, "sheetData":[{ "sheetName":"exportExcelTest", "tabularData":[{ "tabularContent":"工号", "firstRow":1, "lastRow":1, ...
  • POI百万级大数据量EXCEL导出

    万次阅读 多人点赞 2018-09-25 20:18:05
    excel导出,如果数据量在百万级,会出现俩点内存溢出的问题: 1. 查询数据量过大,导致内存溢出。 该问题可以通过分批查询来解决; 2. 最后下载的时候大EXCEL转换的输出流内存溢出;该方式可以通过新版的...
  • C# Datatable数据Excel导出和行列转换

    热门讨论 2011-12-27 00:31:51
    C# 实现DataTable数据的excel导出方法简单包装,行转列的实现
  • js实现Excel导出功能

    千次阅读 2019-05-09 16:21:18
    使用get方式请求后台接口,能获取到导出文件的地址,此时就相当于浏览器打开一个新的链接 <button type="button" id="export" class="btn"><i class="fa fa-download"></i> 导出</button> ...
  • 使用Hutool工具 进行Excel 导出

    千次阅读 2020-04-15 09:51:52
    使用Hutool工具 进行Excel 导出 使用版本 SpringBoot2.X 引入依赖 分别引入 poi 和 hutool 的依赖 <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</...
  • poi导出复杂excel

    2018-11-21 17:48:53
    根据excel模板,拼接出复杂表头(合并行、和并列)的excel,并且能够导出。亲测可以直接运行,内含jar包。如有问题,可私信csdn

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 156,376
精华内容 62,550
关键字:

excel导出