zoukankan      html  css  js  c++  java
  • Apache poi导出excel的一个工具类,同时进行了列宽中文兼容

    直接上代码

    import java.io.File;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.util.HashMap;
    import java.util.Map;
    import org.apache.poi.hssf.usermodel.HSSFCellStyle;
    import org.apache.poi.hssf.usermodel.HSSFFont;
    import org.apache.poi.ss.usermodel.Cell;
    import org.apache.poi.ss.usermodel.CellStyle;
    import org.apache.poi.ss.usermodel.Font;
    import org.apache.poi.ss.usermodel.Row;
    import org.apache.poi.ss.usermodel.Sheet;
    import org.apache.poi.xssf.streaming.SXSSFWorkbook;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    /**
     * 导出excel的工具类,鉴于数据量采用SXSSFWorkbook, 不使用追加的方式,会产生bug
     * 注意:如果真要采用读写已知文件,得使用流的方式,随着数据量增加效率可能会变低
     * @author lxd
     * @version 创建时间:2020年5月13日 下午2:53:20
     * @param <T> 数据源类型,例如ResultSet
     */
    public abstract class ExportExcel<T> {
    	private static final Logger logger = LoggerFactory.getLogger(ExportExcel.class);
    	/**
    	 * 全局的工作表
    	 */
    	private SXSSFWorkbook wb;
    	private String stationUUID;
    	/**
    	 * 存储相应的sheet的行数
    	 */
    	private Map<String,Integer> rownum = new HashMap<String, Integer>();
    	/**
    	 * 所有相应的文件信息
    	 */
    	public static final String PREFIX = "f:/excel/";
    	
    	public String path;
    	
    	static {
    		File file = new File(PREFIX);
    		if(!file.exists()) {
    			file.mkdir();
    		}
    	}
    	
    	
    	
    	private ExportExcel() {
    		super();
    		//大量数据处理的类,1000设置内存中存在的行数
    		wb = new SXSSFWorkbook(1000);
    	}
    	
    
    
    	public ExportExcel(String sn, String fileName) {
    		this();
    		this.path = PREFIX + fileName +".xlsx";
    	}
    
    
    
    
    	
    	/**
    	 * 
    	 * @param sheetName 表名
    	 * @param columns 列名
    	 * @param rs 要处理的结果集
    	 */
    	public void export(String sheetName,String[] columns, T dataSource) {
    		Sheet sheet = null;
    		Row row = null;
    		Cell cell = null;
    		
    		// 创建表头单元格样式
    		CellStyle headerStyle = wb.createCellStyle();
    		headerStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);
    		headerStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
    		headerStyle.setBorderTop(HSSFCellStyle.BORDER_THIN);
    		headerStyle.setBorderRight(HSSFCellStyle.BORDER_THIN);
    		headerStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN);
    		headerStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);
    		Font headerFont = wb.createFont();
    		headerFont.setFontHeightInPoints((short) 12);
    		headerFont.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
    		headerStyle.setFont(headerFont);
    		headerStyle.setWrapText(false);// 自动换行
    
    		// 创建数据行单元格样式
    		CellStyle style = wb.createCellStyle();
    		style.setAlignment(CellStyle.ALIGN_LEFT); // 创建一个居中格式
    		style.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
    		style.setBorderBottom(CellStyle.BORDER_THIN); // 下边框
    		style.setBorderLeft(CellStyle.BORDER_THIN);// 左边框
    		style.setBorderTop(CellStyle.BORDER_THIN);// 上边框
    		style.setBorderRight(CellStyle.BORDER_THIN);// 右边框
    		style.setWrapText(false);//是否自动换行文字内容
    		//获取相应的sheet
    		sheet = wb.getSheet(sheetName);
    		if(null == sheet) {
    			sheet = wb.createSheet(sheetName);
    			//设置列名,相关的电站名称和YBU2
    			row = sheet.createRow(0);
    			for (int i = 0; i < columns.length; i++) {
    				cell = row.createCell(i);
    				cell.setCellValue(columns[i]);
    				cell.setCellStyle(headerStyle);
    				sheet.setColumnWidth(i, (columns[i].getBytes().length+2)*256*3/4);
    				//与中文不兼容
    //				sheet.autoSizeColumn(i);
    			}
    			rownum.put(sheetName, 1);
    		}
    		
    		dataHandle(sheet, dataSource);
    	
    		
    		
    	}
    	
    	/**
    	 * 需要被实现的数据处理的方法
    	 * @param sheet 处理的表单页面
    	 * @param dataSource 需要处理的数据源
    	 */
    	public abstract void dataHandle(Sheet sheet,T dataSource);
    	
    	
    	public void flush2disk() {
    		//写入相关文件
    		try {
    			FileOutputStream fos = new FileOutputStream(new File(path));
    			try {
    				wb.write(fos);
    			} catch (IOException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			}
    			fos.close();
    		} catch (FileNotFoundException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		} catch (IOException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    	}
    	
    
    }
    

    几点说明

    1、示例代码采用的是SXSSFWorkbook,支持大数据量写入,不支持文件的追加方式

    2、poi本身提供了sheet.autoSizeColumn(i); 方法,但是只支持英文;对于中文采用sheet.setColumnWidth(i, (columns[i].getBytes().length+2)*256*3/4); 这种方式,具体计算值可以调整

    3、由于采用的SXSSFWorkbook(1000),当写入行数超过1000时,会将多余的行写入硬盘,所以这时候去读取第一行的时候会报错,所以在最开始就根据中文列名进行列宽设置

    4、具体使用的时候继承上面的类,实现dataHandle方法即可

  • 相关阅读:
    Qtranslate是Win10系统的一款非常小众的翻译神器,真的是办公人员利器
    大文件查找软件(WizTree) v3.37 ---非常快
    DirPrintOK --- 将文件以树的形式列出、可导出到excel、html文件,用于整理电脑的文件,非常好用
    Linux五大类常用命令
    Android pm list 命令查看手机安装的apk信息
    Android adb命令列出当前设备所有apk安装的路径和包名
    Win10 Python2.7.6 如何使用pip命令?如何离线安装第三方模块?PyCharm设置Python2.7.6,、wxPython安装
    证件照在线免费移除背景或更换背景
    Ubuntu wps办公软件快捷键
    根据书籍的ISBN号查询书籍信息
  • 原文地址:https://www.cnblogs.com/marshwinter/p/12983638.html
Copyright © 2011-2022 走看看