ExcelExportUtiler excel工具類
阿新 • • 發佈:2018-12-31
public class ExcelExportUtiler {
private static Log log = LogFactory.getLog(ExcelExportUtiler.class);
/*工作薄*/
private HSSFWorkbook workbook;
/*預設格子寬度*/
private int defaultColumnWidth = 20;
/*sheet頁的名稱*/
private String sheetName;
/*預設標題字型*/
private HSSFFont defaultTitleFont;
/*預設內容字型*/
private HSSFFont defaultContentFont;
/*預設標題風格*/
private HSSFCellStyle defaultTitleStyle;
/*預設內容風格*/
private HSSFCellStyle defaultContentStyle;
/*最後一個sheet頁索引*/
private int lastSheetIndex = 0;
public HSSFWorkbook getWorkbook() {
return workbook;
}
public int getDefaultColumnWidth() {
return defaultColumnWidth;
}
public String getSheetName() {
return sheetName;
}
public HSSFFont getDefaultTitleFont() {
return defaultTitleFont;
}
public HSSFFont getDefaultContentFont() {
return defaultContentFont;
}
public HSSFCellStyle getDefaultTitleStyle() {
return defaultTitleStyle;
}
public HSSFCellStyle getDefaultContentStyle() {
return defaultContentStyle;
}
public ExcelExportUtiler(){
this(null,0,null,null,null,null,null);
}
public ExcelExportUtiler(int defaultColumnWidth){
this(defaultColumnWidth,null);
}
public ExcelExportUtiler(String sheetName){
this(0,sheetName);
}
public ExcelExportUtiler(int defaultColumnWidth, String sheetName){
this(null,defaultColumnWidth,sheetName);
}
public ExcelExportUtiler(HSSFWorkbook workbook, int defaultColumnWidth, String sheetName){
this(workbook,defaultColumnWidth,sheetName,null,null,null,null);
}
public ExcelExportUtiler(HSSFWorkbook workbook, int defaultColumnWidth, String sheetName, HSSFFont defaultTitleFont, HSSFFont defaultContentFont, HSSFCellStyle defaultTitleStyle, HSSFCellStyle defaultContentStyle){
if(workbook == null){
this.workbook = new HSSFWorkbook();
}else{
this.workbook = workbook;
}
if(defaultColumnWidth == 0){
this.defaultColumnWidth = 20;
}else{
this.defaultColumnWidth = defaultColumnWidth;
}
if(sheetName == null || "".equals(sheetName.trim())){
this.sheetName = "sheet";
}else{
this.sheetName = sheetName;
}
if(defaultTitleFont == null){
this.defaultTitleFont = getDefaultTitleFont(this.workbook);
}else{
this.defaultTitleFont = defaultTitleFont;
}
if(defaultContentFont == null){
this.defaultContentFont = getDefaultContentFont(this.workbook);
}else{
this.defaultContentFont = defaultContentFont;
}
if(defaultTitleStyle == null){
this.defaultTitleStyle = getDefaultTitleStyle(this.workbook);
}else{
this.defaultTitleStyle = defaultTitleStyle;
}
if(defaultContentStyle == null){
this.defaultContentStyle = getDefaultContentStyle(this.workbook);
}else{
this.defaultContentStyle = defaultContentStyle;
}
}
/*獲取預設標題字型*/
public static HSSFFont getDefaultTitleFont(HSSFWorkbook workbook){
HSSFFont titleFont = workbook.createFont();
titleFont.setColor(HSSFColor.BLACK.index); //字型顏色
titleFont.setFontHeightInPoints((short) 9); //字號
titleFont.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD); //粗體
titleFont.setFontName("微軟雅黑"); //微軟雅黑
return titleFont;
}
/*獲取預設內容字型*/
public static HSSFFont getDefaultContentFont(HSSFWorkbook workbook){
HSSFFont contentFont = workbook.createFont(); //定義內容字型樣式
contentFont.setColor(HSSFColor.BLACK.index); //字型顏色
contentFont.setFontHeightInPoints((short) 9); //字號
contentFont.setBoldweight(HSSFFont.BOLDWEIGHT_NORMAL); //普通粗細
contentFont.setFontName("微軟雅黑"); //微軟雅黑
return contentFont;
}
/*獲取預設標題樣式*/
public static HSSFCellStyle getDefaultTitleStyle(HSSFWorkbook workbook){
HSSFCellStyle titleStyle = workbook.createCellStyle();
titleStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN); //設定底部邊線
titleStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN); //設定左部邊線
titleStyle.setBorderRight(HSSFCellStyle.BORDER_THIN); //設定右部邊線
titleStyle.setBorderTop(HSSFCellStyle.BORDER_THIN); //設定頂部邊線
titleStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER); //表頭內容水平居中
titleStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER); //表頭內容垂直居中
titleStyle.setFont(getDefaultTitleFont(workbook)); //設定該字型樣式
titleStyle.setWrapText(true);
return titleStyle;
}
/*獲取預設內容樣式*/
public static HSSFCellStyle getDefaultContentStyle(HSSFWorkbook workbook){
HSSFCellStyle contentStyle = workbook.createCellStyle();
contentStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN); //設定底部邊線
contentStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN); //設定左部邊線
contentStyle.setBorderRight(HSSFCellStyle.BORDER_THIN); //設定右部邊線
contentStyle.setBorderTop(HSSFCellStyle.BORDER_THIN); //設定頂部邊線
contentStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER); //表頭內容水平居中
contentStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER); //表頭內容垂直居中
contentStyle.setFont(getDefaultContentFont(workbook)); //設定該字型樣式
contentStyle.setWrapText(true);
return contentStyle;
}
/**
* 提示使用者下載excel
* @param response 響應物件
* @param fileName excel檔名
* create by ronghui.xiao @2015-8-5
*/
public static void downloadExcel(HSSFWorkbook workbook , HttpServletResponse response , String fileName){
try{
if(StringUtils.isNotBlank(fileName)){
fileName = new String(fileName.getBytes("gb2312"), "iso8859-1"); //給檔名重新編碼
}else{
fileName = "excel";
}
response.setContentType("text/html;charset=utf-8"); //設定響應編碼
response.setContentType("application/x-msdownload"); //設定為檔案下載
response.addHeader("Content-Disposition", "attachment;filename=" + fileName + ".xls"); //設定響應頭資訊
OutputStream outputStream = response.getOutputStream(); //建立輸出流
workbook.write(outputStream); //把工作薄寫進流中
outputStream.close();
}catch (IOException e){
log.error(e);
}
}
/**
* 提示使用者下載excel
* @param response 響應物件
* @param fileName excel檔名
* create by ronghui.xiao @2015-8-5
*/
public void downloadExcel(HttpServletResponse response , String fileName){
try{
if(StringUtils.isNotBlank(fileName)){
fileName = new String(fileName.getBytes("gb2312"), "iso8859-1"); //給檔名重新編碼
}else{
fileName = "excel";
}
response.setContentType("text/html;charset=utf-8"); //設定響應編碼
response.setContentType("application/x-msdownload"); //設定為檔案下載
response.addHeader("Content-Disposition", "attachment;filename=" + fileName + ".xls"); //設定響應頭資訊
OutputStream outputStream = response.getOutputStream(); //建立輸出流
workbook.write(outputStream); //把工作薄寫進流中
outputStream.close();
}catch (IOException e){
log.error(e);
}
}
/**
* 提示使用者下載excel
* @function 對ie瀏覽器和firefox進行了相容,不會出現亂碼問題瀏
* @author junqiang.qiu
* @date 2016年12月8日
*/
public void downloadExcel(HttpServletRequest request,HttpServletResponse response,String fileName ){
String agent = request.getHeader("USER-AGENT").toLowerCase();
String codedFileName;
try {
codedFileName = java.net.URLEncoder.encode(fileName, "UTF-8"); //給檔名重新編碼
/*這裡對火狐瀏覽器做了設定*/
if (agent.contains("firefox")) {
response.setCharacterEncoding("utf-8");
response.setHeader("content-disposition", "attachment;filename=" + new String(fileName.getBytes(), "ISO8859-1") + ".xls");
} else {
/*其他瀏覽器*/
response.setHeader("content-disposition", "attachment;filename=" + codedFileName + ".xls");
}
response.setContentType("text/html;charset=utf-8"); //設定響應編碼
response.setContentType("application/x-msdownload"); //設定為檔案下載
OutputStream outputStream = response.getOutputStream(); //建立輸出流
workbook.write(outputStream); //把工作薄寫進流中
outputStream.close();
} catch (Exception e) {
log.error(e);
}
}
/**
* @function 建立Excel,在伺服器端或者是本地
* @author junqiang.qiu
* @date 2017年1月12日
*/
public void createExcel(String path,String fileName){
/*這裡使用File.separator是Java定義的一個列舉,這樣就可以跨平臺,對應Windows和linux是不一樣的*/
try {
String param=null;
param=path+File.separator+fileName+".xls";
FileOutputStream fos=new FileOutputStream(param);
workbook.write(fos);
fos.close();
} catch (Exception e) {
log.info("建立excel失敗"+e);
}
}
/**
* 新增標題行
* @param titles 標題集合
* @param rowHeight 行高
*/
public void addTitlesRow(Collection<String> titles , int rowHeight){
try{
if(titles != null && rowHeight > 0){
int rowIndex = 0;
HSSFSheet sheet = workbook.getSheet(sheetName);
/*總是獲取最後一頁,第一次則建立sheet頁*/
if(sheet == null){
sheet = workbook.createSheet(sheetName);
}else{
sheet = workbook.getSheetAt(lastSheetIndex);
rowIndex = sheet.getLastRowNum() + 1;
}
//若當前sheet頁超過最大條數65536,則再建立一個sheet頁
if(rowIndex > 65535){
lastSheetIndex ++;
sheet = workbook.createSheet(sheetName + lastSheetIndex);
rowIndex = 0;
}
sheet.setDefaultColumnWidth(defaultColumnWidth);
/*建立標題行*/
HSSFRow row = sheet.createRow(rowIndex);
row.setHeightInPoints(rowHeight);
Iterator<String> iterator = titles.iterator();
int index = 0;
while(iterator.hasNext()){
String title = iterator.next();
HSSFCell cell = row.createCell(index); //給該行建立單元格
cell.setCellValue(title); //給單元格放入標題
cell.setCellStyle(defaultTitleStyle);
index ++ ;
}
}
}catch (Exception e){
log.error("新增標題行發生錯誤==>" , e);
}
}
/**
* 新增內容行
* @param titleKeyMap 標題和mapList中key的對應
* @param mapList 內容集合
* @param rowHeight 內容行行高
*/
public void addContentRow(Map<String,String> titleKeyMap , List<Map<String,Object>> mapList , int rowHeight ){
try {
if(titleKeyMap != null && rowHeight > 0 && mapList != null ){
int rowIndex = 0;
HSSFSheet sheet = workbook.getSheet(sheetName);
/*總是獲取最後一頁,第一次則建立sheet頁*/
if(sheet == null){
sheet = workbook.createSheet(sheetName);
sheet.setDefaultColumnWidth(defaultColumnWidth);
}else{
sheet = workbook.getSheetAt(lastSheetIndex);
rowIndex = sheet.getLastRowNum() + 1;
}
/*取出標題*/
List<String> titles = new ArrayList<String>(titleKeyMap.keySet());
/*根據資料的條數來建立表格行*/
for(Map<String,Object> map : mapList){
//若當前sheet頁超過最大條數65536,則再建立一個sheet頁
if(rowIndex > 65535){
lastSheetIndex ++;
sheet = workbook.createSheet(sheetName + lastSheetIndex);
sheet.setDefaultColumnWidth(defaultColumnWidth);
rowIndex = 0;
}
HSSFRow row = sheet.createRow(rowIndex++);
row.setHeightInPoints(rowHeight);
for( int k = 0 ; k < titleKeyMap.size(); k ++){
HSSFCell cell = row.createCell(k);
String key = titleKeyMap.get(titles.get(k));
String value = (map.get(key) != null) ? map.get(key).toString() : "" ;
cell.setCellValue(value);
cell.setCellStyle(defaultContentStyle);
}
}
}
}catch (Exception e){
log.error("新增內容行發生錯誤==>", e);
}
}
/**
* 新增橫向的標題-值的行
* @param titleValueRow
*/
public void addTitleValueRow(TitleValueRow titleValueRow){
try {
int rowIndex = 0;
HSSFSheet sheet = workbook.getSheet(sheetName);
/*總是獲取最後一頁,第一次則建立sheet頁*/
if(sheet == null){
sheet = workbook.createSheet(sheetName);
}else{
sheet = workbook.getSheetAt(lastSheetIndex);
rowIndex = sheet.getLastRowNum() + 1;
}
//若當前sheet頁超過最大條數65536,則再建立一個sheet頁
if(rowIndex > 65535){
lastSheetIndex ++;
sheet = workbook.createSheet(sheetName + lastSheetIndex);
rowIndex = 0;
}
sheet.setDefaultColumnWidth(defaultColumnWidth);
/*建立該行*/
HSSFRow row = sheet.createRow(rowIndex);
row.setHeightInPoints(titleValueRow.getRowHeight());
List<TitleValue> titleValueList = titleValueRow.getTitleValueList();
for(int i = 0 ; i < titleValueRow.getCellsSize() ; i ++ ){
row.createCell(i).setCellStyle(defaultContentStyle);
}
int curCellIndex = 0;
for(TitleValue titleValue :titleValueList){
/*給單元格賦值*/
HSSFCell cell = row.getCell(curCellIndex);
cell.setCellValue(titleValue.getTitle());
if(titleValue.getTitleCells() > 1){
sheet.addMergedRegion(new CellRangeAddress(rowIndex,rowIndex,curCellIndex,(curCellIndex + titleValue.getTitleCells() -1)));
}
curCellIndex += titleValue.getTitleCells();
cell.setCellStyle(defaultTitleStyle);
if(titleValue.getValueCells() >= 1){
cell = row.getCell(curCellIndex);
cell.setCellValue(titleValue.getValue());
}
if(titleValue.getValueCells() > 1){
sheet.addMergedRegion(new CellRangeAddress(rowIndex,rowIndex,curCellIndex,curCellIndex + titleValue.getValueCells() -1));
}
curCellIndex += titleValue.getValueCells();
}
}catch (Exception e){
log.error("新增橫向的標題-值的行==>",e);
}
}
/**
* 標題和值行的類
*/
public static class TitleValueRow{
/*標題和值的集合*/
private List<TitleValue> titleValueList;
/*該行所佔用的總格子數*/
private int cellsSize = 0;
/*該行所佔用的高度*/
private float rowHeight = 20;
public TitleValueRow(){
this.titleValueList = new ArrayList<TitleValue>();
}
public TitleValueRow(List<TitleValue> titleValueList , int rowHeight){
if(titleValueList != null && titleValueList.size() > 0){
this.titleValueList = titleValueList;
for(TitleValue titleValue : titleValueList){
cellsSize += titleValue.getTitleCells() + titleValue.getValueCells();
}
}else{
this.titleValueList = new ArrayList<TitleValue>();
}
if(rowHeight > 0){
this.rowHeight = rowHeight;
}
}
public void addTitleValue(TitleValue titleValue){
titleValueList.add(titleValue);
cellsSize ++ ;
}
public float getRowHeight() {
return rowHeight;
}
public void setRowHeight(float rowHeight) {
this.rowHeight = rowHeight;
}
public List<TitleValue> getTitleValueList() {
return titleValueList;
}
public void setTitleValueList(List<TitleValue> titleValueList) {
this.titleValueList = titleValueList;
}
public int getCellsSize() {
return cellsSize;
}
public void setCellsSize(int cellsSize) {
this.cellsSize = cellsSize;
}
}
/**
* 橫向的標題和行:
* 格式為 ==> xxxx標題 : 值
*/
public static class TitleValue{
/*標題*/
private String title;
/*值*/
private String value;
/*標題所佔用的格子數*/
private int titleCells = 1;
/*內容所佔用的格子數*/
private int valueCells = 1;
/*構造方法*/
public TitleValue(){
}
public TitleValue(String title , String value){
this.title = title;
this.value = value;
}
public TitleValue(String title , String value , int titleCells , int valueCells){
this.title = title;
this.value = value;
this.titleCells = titleCells;
this.valueCells = valueCells;
}
public TitleValue(String title , String value , int titleCells){
this.title = title;
this.value = value;
this.titleCells = titleCells;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public int getTitleCells() {
return titleCells;
}
public void setTitleCells(int titleCells) {
this.titleCells = titleCells;
}
public int getValueCells() {
return valueCells;
}
public void setValueCells(int valueCells) {
this.valueCells = valueCells;
}
}
/**
* @function 匯出一個具有錯誤資訊的excel
* @param fileName 匯出檔名
* @param msg 錯誤資訊
* @author ronghui.xiao
* @date 2017年3月10日
*/
public static void exportErrorMsg(HttpServletResponse response , String fileName , String msg){
ExcelExportUtiler excelExportUtiler = new ExcelExportUtiler("錯誤資訊");
TitleValue titleValue = new TitleValue(msg,"",10,0);
TitleValueRow row = new TitleValueRow(Arrays.asList(titleValue) , 50);
excelExportUtiler.addTitleValueRow(row);
excelExportUtiler.downloadExcel(response, fileName);
}
/**
* @function 傳入一個http響應物件,模擬匯出一個excel
* @param response http響應物件
* @author ronghui.xiao
* @date 2015年8月5日
* update at 2017年4月5日 by ronghui.xiao
*/
public static void testExcelPort(HttpServletResponse response){
//建立一個例項,可以根據需要傳入不同的引數,預設sheetName為"sheet"
ExcelExportUtiler excelExportUtiler = new ExcelExportUtiler();
Map<String,String> titleKeyMap = new LinkedHashMap<String,String>();
titleKeyMap.put("使用者名稱", "userName");
titleKeyMap.put("密碼", "password");
titleKeyMap.put("性別", "sex");
titleKeyMap.put("年齡", "age");
titleKeyMap.put("愛好", "hobby");
titleKeyMap.put("公司", "company");
//模擬10萬條資料(本工具類支援任意數量和任意excel版本的匯出,超過65536條將會分頁)
List<Map<String,Object>> mapList = new ArrayList<Map<String,Object>>();
for(int i = 0 ; i < 100000 ; i ++){
Map<String,Object> map = new HashMap<String,Object>();
map.put("userName","小明" + i);
map.put("age",i);
map.put("company","蜀國" + i);
map.put("hobby","做作業");
map.put("password","1232323" + i);
map.put("sex","男");
mapList.add(map);
}
/*新增橫向的行*/
List<TitleValue> titleValues = new ArrayList<TitleValue>();
titleValues.add(new TitleValue("測試excel工具類","",6,0));
TitleValueRow row = new TitleValueRow(titleValues , 50);
excelExportUtiler.addTitleValueRow(row);
/*新增標題行*/
excelExportUtiler.addTitlesRow(titleKeyMap.keySet(), 30);
/*新增內容行*/
excelExportUtiler.addContentRow(titleKeyMap, mapList, 20);
/*新增橫向的行*/
List<TitleValue> titleValues1 = new ArrayList<TitleValue>();
titleValues1.add(new TitleValue("末尾也可以新增", "哈哈哈哈", 3, 3));
TitleValueRow row2 = new TitleValueRow(titleValues1 , 50);
excelExportUtiler.addTitleValueRow(row2);
/*下載*/
excelExportUtiler.downloadExcel(response,"使用者資訊表");
}
public static void ExcelPort(HttpServletResponse response,List<String> keys,List<String> titles,String fileName,List<Map<String, Object>> dataList){
//建立一個例項,可以根據需要傳入不同的引數,預設sheetName為"sheet"
ExcelExportUtiler excelExportUtiler = new ExcelExportUtiler();
Map<String,String> titleKeyMap = new LinkedHashMap<String,String>();
//一般keys和titles大小一定要相等,或者keys長度>titles長度
for(int i=0;i<titles.size();i++){
titleKeyMap.put(titles.get(i),keys.get(i));
}
/*新增橫向的行*/
List<TitleValue> titleValues = new ArrayList<TitleValue>();
titleValues.add(new TitleValue(fileName,"",titles.size(),0));
TitleValueRow row = new TitleValueRow(titleValues , 30);
excelExportUtiler.addTitleValueRow(row);
/*新增標題行*/
excelExportUtiler.addTitlesRow(titleKeyMap.keySet(), 30);
/*新增內容行*/
excelExportUtiler.addContentRow(titleKeyMap, dataList, 20);
/*新增橫向的行*/
List<TitleValue> titleValues1 = new ArrayList<TitleValue>();
// titleValues1.add(new TitleValue("末尾也可以新增", "哈哈哈哈", 3, 3));
TitleValueRow row2 = new TitleValueRow(titleValues1 , 50);
excelExportUtiler.addTitleValueRow(row2);
/*下載*/
excelExportUtiler.downloadExcel(response,fileName);
}
}