excel导出工具包

package com.ljyq.central.common.util;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.*;

public final class Export {

public static final boolean excel07 = true;
public static final boolean excel03 = ! excel07;
private static final String DEFAULT_SHEET_NAME = "工作表1";

/**
* 导出文件! 在 Controller 中调用!
*
* @param type 类型: csv 或 xls xlsx 三种, 传 null 则默认是 csv
* @param name 导出的文件名, 若导出成 excel, sheet 名也是这个
* @param titleMap 标题(key 为英文, value 为标题内容)
* @param dataList 导出的数据(数组中的每个 object 都是一行, object 中的属性名与标题中的 key 相对)
*/
public static void export ( Type type , String name , LinkedHashMap< String, String > titleMap ,
List< ? > dataList , HttpServletResponse response ) throws IOException {
if ( type == null ) type = Type.CSV;

// 导出文件加上当前时间
String fileName = encodeName( name ) + "." + type.getValue().toLowerCase();
if ( type.isExcel() ) {
LinkedHashMap linkedHashMap = new LinkedHashMap( Collections.singletonMap( name , dataList ) );
exportXls( response , fileName , titleMap , linkedHashMap );
} /*else if ("pdf".equalsIgnoreCase(type)) {
// ...
}*/ else {
exportCsv( response , fileName , titleMap , dataList );
}
}

public static String encodeName ( String name ) {
String fileName = name + "-" + ( DateUtils.currentTimeString() );
String userAgent = RequestUtils.getUserAgentHeader();
if ( StringUtils.isNotBlank( userAgent ) && userAgent.contains( "Mozilla" ) ) {
// Chrome, Firefox, Safari etc...
fileName = new String( fileName.getBytes() , StandardCharsets.ISO_8859_1 );
} else {
try {
fileName = URLEncoder.encode( fileName , StandardCharsets.UTF_8.name() );
} catch ( UnsupportedEncodingException e ) {
// ignore
}
}
return fileName;
}

private static void setResponse ( HttpServletResponse response , String type , String fileName ) {
response.setContentType( "text/" + type );
response.setContentType( "application/octet-stream; charset=utf-8" );
response.setHeader( "Content-Disposition" , "attachment;filename=" + fileName );
}

public static void exportDoc ( HttpServletResponse response , String fileName , String html ) throws IOException {
// 将 html 导出成 doc 文档
setResponse( response , "doc" , fileName );

POIFSFileSystem fs = new POIFSFileSystem();
fs.createDocument( new ByteArrayInputStream( html.getBytes( StandardCharsets.UTF_8 ) ) , "WordDocument" );
fs.writeFilesystem( response.getOutputStream() );
}

public static void exportXls ( HttpServletResponse response , String fileName ,
LinkedHashMap< String, String > titleMap ,
LinkedHashMap< String, List< ? > > dataMap ) throws IOException {
// 导出 excel
setResponse( response , "xls" , fileName );
exportXls( response.getOutputStream() , Type.is07Suffix( fileName ) , titleMap , dataMap );
}

public static void exportXls ( OutputStream outputStream ,
boolean isExcel07 ,
String sheetName ,
LinkedHashMap< String, String > titleMap ,
List< ? > dataList ) throws IOException {
exportXls( outputStream ,
isExcel07 ,
titleMap ,
new LinkedHashMap<>( Collections.singletonMap( sheetName , dataList ) ) );
}

public static void exportXls ( OutputStream outputStream ,
LinkedHashMap< String, String > titleMap ,
List< ? > dataList ) throws IOException {
exportXls( outputStream ,
excel03 ,
titleMap ,
new LinkedHashMap<>( Collections.singletonMap( DEFAULT_SHEET_NAME , dataList ) )
);
}

public static void exportXls ( OutputStream outputStream ,
boolean isExcel07 ,
LinkedHashMap< String, String > titleMap ,
List< ? > dataList ) throws IOException {
exportXls( outputStream ,
isExcel07 ,
titleMap ,
new LinkedHashMap<>( Collections.singletonMap( DEFAULT_SHEET_NAME , dataList ) ) );
}

/**
* 导出Excel
*
* @param outputStream : 输出流
* @param isExcel07 : 是否microsoft excel 2007(xlsx)
* @param titleMap : 属性名为 key, 对应的标题为 value
* @param dataMap : ( key : sheetname,value : sheet数据 ) , 如果你只要一个表,那么可以这样:new LinkedHashMap<>( Collections.singletonMap( sheetName , dataMap ) ) )
* @throws IOException
*/
public static void exportXls ( OutputStream outputStream , boolean isExcel07 ,
LinkedHashMap< String, String > titleMap ,
LinkedHashMap< String, List< ? > > dataMap ) throws IOException {
exportXlsToWorkbook( isExcel07 , titleMap , dataMap ).write( outputStream );
}

public static Workbook exportXlsToWorkbook ( boolean isExcel07 ,
LinkedHashMap< String, String > titleMap ,
List< ? > dataList ) throws IOException {
return ExportExcel.handle( isExcel07 ,
titleMap ,
new LinkedHashMap<>( Collections.singletonMap( DEFAULT_SHEET_NAME , dataList ) ) );
}

public static Workbook exportXlsToWorkbook ( boolean isExcel07 ,
LinkedHashMap< String, String > titleMap ,
LinkedHashMap< String, List< ? > > dataMap ) throws IOException {
return ExportExcel.handle( isExcel07 , titleMap , dataMap );
}

public static void exportTxt ( HttpServletResponse response , String fileName , String content ) throws
IOException {
// 导出 txt
setResponse( response , "plain" , fileName );
response.getOutputStream().write( content.getBytes( StandardCharsets.UTF_8 ) );
}

public static void exportCsv ( HttpServletResponse response , String fileName ,
LinkedHashMap< String, String > titleMap , List< ? > dataList ) throws IOException {
String content = convertCsv( titleMap , dataList );

// 导出 csv
setResponse( response , "csv" , fileName );
response.getOutputStream().write( content.getBytes( StandardCharsets.UTF_8 ) );

POIFSFileSystem poifsFileSystem = new POIFSFileSystem();
poifsFileSystem.createDocument( new ByteArrayInputStream( content.getBytes( "GBK" ) ) , "WordDocument" );
poifsFileSystem.writeFilesystem( response.getOutputStream() );
}

private static String convertCsv ( LinkedHashMap< String, String > titleMap , List< ? > dataList ) {

// 没有数据或没有标题, 返回一个内容为空的文件
if ( MapUtils.isEmpty( titleMap ) || CollectionUtils.isEmpty( dataList ) ) return StringUtils.EMPTY;

// 用英文逗号(,)隔开列, 用换行(\n)隔开行, 内容中包含了逗号的需要用双引号包裹, 若内容中包含了双引号则需要用两个双引号表示.
StringBuilder sbd = new StringBuilder();
int i = 0;
for ( String title : titleMap.values() ) {
sbd.append( handleCsvContent( title ) );
i++;
if ( i != titleMap.size() ) sbd.append( "," );
}
for ( Object data : dataList ) {
sbd.append( "\n" );
i = 0;
for ( String title : titleMap.keySet() ) {
sbd.append( handleCsvContent(
ReflectionPlusUtils.invokeFieldGettersMethodToCustomizeString( data , title ) )
);
i++;
if ( i != titleMap.size() ) sbd.append( "," );
}
}
return sbd.toString();
}

private static String handleCsvContent ( String content ) {
return "\"" + content.replace( "\"" , "\"\"" ) + "\"";
}

public static String addXlsSuffix ( String fileName ) {
return StringPrivateUtils.getString( fileName ) + ".xls";
}

public static String addXlsxSuffix ( String fileName ) {
return StringPrivateUtils.getString( fileName ) + ".xlsx";
}

public enum Type {
MS03( "xls" ), MS07( "xlsx" ), CSV( "csv" );

private String value;

Type ( String value ) {
this.value = value;
}

public static boolean is07Suffix ( String fileName ) {
return fileName.toLowerCase().endsWith( Type.MS07.getValue().toLowerCase() );
}

public static boolean is03Suffix ( String fileName ) {
return fileName.toLowerCase().endsWith( Type.MS03.getValue().toLowerCase() );
}

public String getValue () {
return value;
}

public boolean isExcel () {
return Arrays.asList( MS03 , MS07 ).contains( this );
}
}

private static final class ExportExcel {
/** excel 2003 的最大列数是 256 列, 2007 及以上版本是 16384 列 */
private static final int CELL_TOTAL = 256;
/** excel 2003 的最大行数是 65536 行, 等同于 (2 << 15) - 1, 2007 开始的版本是 1048576 行 */
private static final int ROW_TOTAL = 65536;

/** 标题行的字体大小 */
private static final short HEAD_FONT_SIZE = 11;
/** 其他内容的字体大小 */
private static final short FONT_SIZE = 10;
/** 行高. 要比上面的字体大一点! */
private static final short ROW_HEIGHT = 15;

private static boolean must07 ( int cellSize ) {
return cellSize > CELL_TOTAL;
}

/**
* 返回一个 excel 工作簿
*
* @param excel07 是否返回 microsoft excel 2007 的版本
* @param titleMap 属性名为 key, 对应的标题为 value, 为了处理显示时的顺序, 因此使用 linkedHashMap
* @param dataMap 以「sheet 名」为 key, 对应的数据为 value(每一行的数据为一个 Object)
*/
private static Workbook handle ( boolean excel07 , LinkedHashMap< String, String > titleMap ,
LinkedHashMap< String, List< ? > > dataMap ) {
// 如果要导出的不是 07 的版本, 但是导出的列却大于 256 列, 则只能导出 07 版本
if ( ! excel07 ) {
excel07 = must07( titleMap.size() );
}

// 声明一个工作薄. HSSFWorkbook 是 Office 2003 的版本, XSSFWorkbook 是 2007
Workbook workbook = excel07 ? new XSSFWorkbook() : new HSSFWorkbook();
// 没有数据, 或者没有标题, 都直接返回
if ( MapUtils.isEmpty( dataMap ) || MapUtils.isEmpty( titleMap ) ) return workbook;

// 头样式
CellStyle headStyle = createHeadStyle( workbook );
// 内容样式
CellStyle contentStyle = createContentStyle( workbook );

// sheet
Sheet sheet;
// 行
Row row;
// 列
Cell cell;
// 表格数 行索引 列索引 数据起始索引 数据结束索引
int sheetCount, rowIndex, cellIndex, fromIndex, toIndex;
// 大小 数据
int size;
List< ? > excelList;

for ( Map.Entry< String, List< ? > > entry : dataMap.entrySet() ) {
// 当前 sheet 的数据
excelList = entry.getValue();
if ( CollectionUtils.isNotEmpty( excelList ) ) {
// 一个 sheet 数据过多 excel 处理会出错, 分多个 sheet
size = excelList.size();
sheetCount = ( ( size % ROW_TOTAL == 0 ) ? ( size / ROW_TOTAL ) : ( size / ROW_TOTAL + 1 ) );
for ( int i = 0 ; i < sheetCount ; i++ ) {
// 构建 sheet, 带名字
sheet = workbook.createSheet( entry.getKey() + ( sheetCount > 1
? ( "-" + ( i + 1 ) )
: StringUtils.EMPTY ) );

// 每个 sheet 的标题行
rowIndex = 0;
cellIndex = 0;
row = sheet.createRow( rowIndex );
row.setHeightInPoints( ROW_HEIGHT );
// 每个 sheet 的标题行
for ( String header : titleMap.values() ) {
// 宽度自适应
sheet.autoSizeColumn( cellIndex );
cell = row.createCell( cellIndex );
cell.setCellStyle( headStyle );
cell.setCellValue( header );
cellIndex++;
}
// 冻结第一行
sheet.createFreezePane( 0 , 1 , 0 , 1 );

// 每个 sheet 除标题行以外的数据
fromIndex = ROW_TOTAL * i;
toIndex = ( i + 1 == sheetCount ) ? size : ROW_TOTAL;
for ( Object data : excelList.subList( fromIndex , toIndex ) ) {
if ( data != null ) {
rowIndex++;
// 每行
row = sheet.createRow( rowIndex );
row.setHeightInPoints( ROW_HEIGHT );
cellIndex = 0;
for ( String value : titleMap.keySet() ) {
String cellValue;
if ( data instanceof Map ) {
final Object obj = ( ( Map ) data ).get( value );
cellValue = Objects.isNull( obj ) ? StringUtils.EMPTY : obj.toString();
} else {
cellValue =
ReflectionPlusUtils.invokeFieldGettersMethodToCustomizeString( data ,
value );
}
// 每列
cell = row.createCell( cellIndex );
cell.setCellStyle( contentStyle );
cell.setCellValue( cellValue );
cellIndex++;
}
}
}
}
}
}
return workbook;
}

/** 头样式 */
private static CellStyle createHeadStyle ( Workbook workbook ) {
CellStyle style = workbook.createCellStyle();

style.setAlignment( HorizontalAlignment.LEFT ); // 水平居左
style.setVerticalAlignment( VerticalAlignment.CENTER ); // 垂直居中
// style.setWrapText(true); // 自动换行

Font font = workbook.createFont();
font.setBold( true ); // 粗体
font.setFontHeightInPoints( HEAD_FONT_SIZE );
style.setFont( font );
return style;
}

/** 内容样式 */
private static CellStyle createContentStyle ( Workbook workbook ) {
CellStyle style = workbook.createCellStyle();

style.setAlignment( HorizontalAlignment.LEFT );
style.setVerticalAlignment( VerticalAlignment.CENTER );

Font font = workbook.createFont();
font.setFontHeightInPoints( FONT_SIZE );
style.setFont( font );
return style;
}
}
}

原文地址:https://www.cnblogs.com/dayuss/p/11508125.html

时间: 2024-11-02 19:17:40

excel导出工具包的相关文章

Excel导出工具包pentaho report

1.Pentaho Report介绍 > Pentaho Pentaho 是 Java 平台上著名的商业智能(BI)项目.它包含多个产品以及产品插件.辅助工具,包括 BI 平台(BI Platform).ETL.报表.联机分析.数据挖掘等. > Pentaho report Pentaho Reporting 是 Pentaho 的报表解决方案.它原先是开源项目 JFreeReport,后来容纳进 Pentaho.Pentaho Reporting 采用开源协议是 LGPL. Pentaho

displaytag的Excel导出实践

本文转自 http://lingceng.iteye.com/blog/1820081/ Displaytag官网有1.0, 1.1, 1.2等,注意找到对应的版本.源码和API可以在Maven库中找到.   常规的使用不是问题,这里说说关于Excel导出的问题,中文乱码,使用POI等.我使用的是Displaytag1.1. 基本导出功能   这种情况只需引入displaytag-1.1.jar.   设置column属性media="html"将不会导出,media="ex

ExtJS实现Excel导出

1. 使用POI组件实现excel导出功能 //获取问题列表 List<Suggestion> targetStockList = suggestionService.getSuggestionList(map);           //创建一个新的Excel         HSSFWorkbook workBook = new HSSFWorkbook();         //创建sheet页         HSSFSheet sheet = workBook.createSheet

二十六、【开源框架】EFW框架Winform前端开发之Grid++Report报表、条形码、Excel导出、图表控件

回<[开源]EFW框架系列文章索引>        EFW框架源代码下载V1.2:http://pan.baidu.com/s/1hcnuA EFW框架实例源代码下载:http://pan.baidu.com/s/1o6MAKCa 前言:本章介绍除DotNetBar2控件套件之外的另外一些常用控件,包括Grid++Report报表.条形码.Excel导出.图表控件ZedGraph:类似这些控件网上免费开源的太少了,经过一番对比和使用感受最后决定把这几个控件整合到EFW框架中供大家选择使用: 本

java excel导出

1.  Excel导出的核心方法在ExportExcel类中,使用时请将该类完整的引入. 1 import java.io.IOException; 2 import java.io.OutputStream; 3 import java.lang.reflect.Field; 4 import java.lang.reflect.InvocationTargetException; 5 import java.lang.reflect.Method; 6 import java.text.Si

利用Aspose.Cells完成easyUI中DataGrid数据的Excel导出功能

我准备在项目中实现该功能之前,google发现大部分代码都是利用一般处理程序 HttpHandler实现的服务器端数据的Excel导出,但是这样存在的问题是ashx读取的数据一般都是数据库中视图的数据,难免会含有方便操作的 主键ID这列的记录.现在项目需要在easyUI的DataGrid中显示的数据能全部导出Excel,包括DataGrid中的中文标题,其他的统统不 要. 完成该功能所需的工具和环境:Newtonsoft.Json序列化和反序列化类库.easyUI前端UI框架.HttpHandl

excel导出功能优化

先说说优化前,怎么做EXCEL导出功能的: 1. 先定义一个VO类,类中的字段按照EXCEL的顺序定义,并且该类只能用于EXCEL导出使用,不能随便修改. 2. 将查询到的结果集循环写入到这个VO类中. 3. 将这个VO类的数据集写入到EXCEL中. 缺点: 1.每次做一个功能的excel导出需要定义一个vo类,并且vo类不可随便变更. 2. 从数据库查询到结果集不能直接输出到excel,需要二次遍历写入到vo中. 3. excel导出的顺序必须与vo定义的字段顺序一致,并且输出vo中所有的字段

偷懒小工具 - Excel导出公共类

说明 最近接了一个任务,就是做一个列表的Excel导出功能.并且有很多页面都会使用这个功能. 导出的Excel大体格式如图 很简单的列表,标题加背景色,然后不同类型,显示方式不一样.对齐方式不一样.不同页面除了内容以外,大体形式都差不多. 当时本来是想直接用NPOI,IRow ICell.这样进行拼接页面,最简单也最方便. 但是很多页面,都进行这种类似的设计.我实在是懒得做这种重复功能.所以花了一点时间,整理了一下帮助类. 使用 做好这个帮助类以后只要进行两点调用 1.制作导出Excel的数据模

java反射学习之二万能EXCEL导出

一.EXCEL导出的实现过程 假设有一个对象的集合,现在需要将此集合内的所有对象导出到EXCEL中,对象有N个属性:那么我们实现的方式是这样的: 循环这个集合,在循环集合中某个对象的所有属性,将这个对象的所有属性作为EXCEL的列,该对象占据EXCEL的一行 二.万能EXCEL导出(以JXL为例,jxl.poi等excel导入导出的jar包不做介绍了) 1.创建java工程.引入jxl的jar包 2.直接上代码 Book.java /** * Book对象 * @author bwy * */