导出excel表格的工具类

package com.xinshiyun.fayuan.web.court.utils;

import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.collections.CollectionUtils;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRichTextString;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbookType;

import com.alibaba.dubbo.common.utils.StringUtils;

/**
 * 
 * office excel工具类
 * 
 *
 */
public final class ExcelUtils {
	
	private static final SimpleDateFormat DATE_FORAMT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	
	/**
	 * 
	 * 导出最精简的excel
	 * 
	 * @param headers (不是必填) excel头列 比如: 姓名  年龄  性别 ..
	 * @param datas (必填) 数据列(请确保和列的顺序保持一致)
	 * @param fileName 生成excel的文件名称,如果不传则默认为随机生成
	 * @param request HttpServletRequest
	 * @param response HttpServletResponse
	 * @throws IOException  
	 */
	public static void generateCreateExcel(List<String> headers, List<List<Object>> datas, String fileName,
			HttpServletRequest request, HttpServletResponse response) throws IOException {
		Workbook workbook = generateCreateExcel(headers, datas);
		
		// 文件名处理一下
		fileName = (StringUtils.isBlank(fileName) ? UUID.randomUUID().toString() : fileName) + "."
				+ XSSFWorkbookType.XLSX.getExtension();
		String userAgent = request.getHeader("User-Agent");
        if (userAgent.toUpperCase().contains("MSIE") || userAgent.toUpperCase().contains("RV:11")) {
            fileName = URLEncoder.encode(fileName, StandardCharsets.UTF_8.displayName());
        }
        else {
            fileName = new String(fileName.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1);
        }
        
		response.reset(); // 清空response
		response.setContentType("application/x-msdownload");
		response.setHeader("Connection", "close"); // 表示不能用浏览器直接打开
		response.setHeader("content-disposition", "attachment;filename=" + fileName);
		response.setCharacterEncoding("UTF-8");
		
        // 文件流输出
		try {
			workbook.write(response.getOutputStream());
		}
		catch (IOException e) {
			throw new IOException("could not write to response. cause: ", e);
		}
		finally {
			if (workbook != null)
				workbook.close();
		}
	}
	
	/**
	 * 生成一个workbook
	 * 
	 * @param headers (不是必填) excel头列 比如: 姓名  年龄  性别 ..
	 * @param datas(必填) 数据列(请确保和列的顺序保持一致)
	 * @return
	 */
	public static Workbook generateCreateExcel(List<String> headers, List<List<Object>> datas) {
		
		XSSFWorkbook book = null;
		
		// 如果内容为空则直接返回一个空的book
		if (CollectionUtils.isEmpty(datas)) {
			return book;
		}
		
		// 先创建一发book,并建一个sheet
		book = new XSSFWorkbook();
		XSSFSheet sheet = book.createSheet();
		
		// 设置自适应列宽
		List<Integer> maxCalls = getMaxCall(headers, datas);
		for (int i = 0, j = maxCalls.size(); i < j; i++) {
			// 最大列宽设置
			if (maxCalls.get(i) > 30) {
				sheet.setColumnWidth(i, 30 * 256);
			} else {
				sheet.setColumnWidth(i, maxCalls.get(i) * 256);
			}
		}
		
		// 是否有头,如果有则先把表头建好
		if (CollectionUtils.isNotEmpty(headers)) {
			// 创建第一行,表头行
			XSSFRow titleRow = sheet.createRow(0);
			
			XSSFCell titleCell = null;
			XSSFRichTextString titleText = null;
			// 把表头放到第一个行里面
			for (int i = 0; i < headers.size(); i++) {
				// 有几个列头 就在一行中创建多少个单元格
				titleCell = titleRow.createCell(i);
				
				// 给创建的单元格里面设值
				titleText = new XSSFRichTextString(headers.get(i));
				titleCell.setCellValue(titleText);
			}
		}
		
		// 处理内容
		if (CollectionUtils.isNotEmpty(datas)) {
			
			// 如果有列表头则row重1开始。否则重0开始
			int dataRowIdx = CollectionUtils.isNotEmpty(headers) ? 1 : 0;
			
			XSSFRow dataRow = null; 
			XSSFCell dataCell = null;
			List<Object> dataList = null;
			
			// 开始处理行和单元格
			for (int i = 0; i < datas.size(); i++) {
				
				// 创建内容的行
				dataRow = sheet.createRow(i + dataRowIdx);
				
				dataList = datas.get(i);
				// 将内容放到对应的行中
				for (int j = 0; j < dataList.size(); j++) {
					// 有多少个内容就有多少个单元格
					dataCell = dataRow.createCell(j);
					
					// 设值单元格的值
					setValue(dataCell, dataList.get(j));
				}
			}
		}
		
		return book;
	}
	
	private static void setValue(Cell cell, Object value) {
		
		// 如果是null 则设值为空
		if (Objects.isNull(value)) {
			cell.setCellValue("");
		}
		else if (value.getClass() == String.class) {
			cell.setCellValue(String.valueOf(value));
		}
		else if (value.getClass() == Integer.class) {
			cell.setCellValue((Integer) value);
		}
		else if (value.getClass() == Double.class) {
			cell.setCellValue((Double) value);
		}
		else if (value.getClass() == Date.class) {
			cell.setCellValue(DATE_FORAMT.format(value));
		}
		else if (value.getClass() == Long.class) {
			cell.setCellValue((Long) value);
		}
		else {
			cell.setCellValue(new XSSFRichTextString(String.valueOf(value)));
		}
	}
	
	/**
	 * 最大列宽
	 * 
	 * @param headers
	 * @param datas
	 * @return
	 */
	private static List<Integer> getMaxCall(List<String> headers, List<List<Object>> datas) {
		// 创建最大列宽集合
		List<Integer> maxCall = new ArrayList<>();
		List<List<Integer>> lss = new ArrayList<>();
		// 计算标题行数据的列宽
		List<Integer> hls = new ArrayList<>();
		for (int m = 0; m < headers.size(); m++) {
			int length = headers.get(m).getBytes().length;
			hls.add(length);
			// 最大列宽赋初值
			maxCall.add(0);
		}
		lss.add(hls);
		
		// 计算内容行数据的列宽
		for (int i = 0, j = datas.size(); i < j; i++) {
			List<Integer> dls = new ArrayList<>();
			for (int m = 0, n = datas.get(i).size(); m < n; m++) {
				Object obj = datas.get(i).get(m);
				if (obj == null) {
					dls.add(0);
					continue;
				}
				if (obj.getClass() == Date.class) {
					// 日期格式类型转换
					obj = DATE_FORAMT.format(obj);
				}
				int length = obj.toString().getBytes().length;
				dls.add(length);
			}
			lss.add(dls);
		}
		// 根据列宽计算出每列的最大宽度
		for (int i = 0, j = lss.size(); i < j; i++) {
			for (int m = 0, n = lss.get(i).size(); m < n; m++) {
				Integer a = lss.get(i).get(m);
				Integer b = maxCall.get(m);
				if (a > b) {
					maxCall.set(m, a);
				}
			}
		}
		return maxCall;
	}
	
//	public static void main(String[] args) {
//		List<String> headers = new ArrayList<>();
//		
//		headers.add("姓名");
//		headers.add("性别");
//		headers.add("年龄");
//		
//		List<List<Object>> datas = new ArrayList<>();
//		List<Object> data = new ArrayList<>();
//		
//		data.add("没有数据");
//		datas.add(data);
//		
//		Workbook workbook = generateCreateExcel(headers, datas);
//		OutputStream out = null;
//		try {
//			out = new FileOutputStream(new File("d:/data/1.xlsx"));
//			workbook.write(out);
//			
//			System.out.println("--------- over --------");
//		} catch (IOException e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//		} finally {
//			try {
//				workbook.close();
//			} catch (IOException e) {
//				// TODO Auto-generated catch block
//				e.printStackTrace();
//			}
//			try {
//				out.close();
//			} catch (IOException e) {
//				// TODO Auto-generated catch block
//				e.printStackTrace();
//			}
//		}
//		
//	}
}

List<String> headers:表头

List<List<Object>> datas:表数据

简单易用

猜你喜欢

转载自blog.csdn.net/sheng_xinjun/article/details/81872488