package com.test.util;  

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set; import javax.servlet.http.HttpServletResponse;
import javax.swing.JOptionPane; import org.apache.commons.collections.CollectionUtils;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFDataFormat;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFRichTextString;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.ss.util.CellReference; /**
* @author zhanghk
*/
public class ExcelUtil_Extend {
/**
* @param fileName 文件名称
* @param headers 表头
* @param dataset 数据集
* @param isSortDataSet 是否对数据排序
* @param response HttpServletResponse
* @param mergeBasis 合并基准列 可选
* @param mergeCells 要合并的列 可选
* @param sumCellsMap 要求和的列 可选
* @param timeCells 时间列 可选
* @throws IOException
*/
public static void exportExelMerge(String fileName,final String[] headers,List<String[]> dataset,boolean isSortDataSet,HttpServletResponse response, final Integer[] mergeBasis, final Integer[] mergeCells, final Integer[] sumCells, final Integer[] timeCells) throws IOException{
String title = "Sheet1";
response.setContentType("application/vnd.ms-excel;charset=utf-8");
response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(fileName, "utf-8")); createExcelMerge(title,headers,dataset,isSortDataSet,response.getOutputStream(),mergeBasis,mergeCells,sumCells,timeCells); response.setStatus(HttpServletResponse.SC_OK);
response.flushBuffer();
} /**
* @param title 文件名称
* @param headers 表头
* @param dataset 数据集
* @param isSortDataSet 是否对数据排序
* @param out OutputStream
* @param mergeBasis 合并基准列 可选
* @param mergeCells 要合并的列
* @param sumCells 要求和的列
* @param timeCells 时间列 可选
*/
public static void createExcelMerge(String title, final String[] headers,List<String[]> dataset,boolean isSortDataSet, OutputStream out, final Integer[] mergeBasis, final Integer[] mergeCells, final Integer[] sumCells, final Integer[] timeCells){
HSSFWorkbook workbook = new HSSFWorkbook();
HSSFSheet sheet = workbook.createSheet(title); sheet.setDefaultColumnWidth(15); // 设置表格默认列宽度为15个字节 HSSFCellStyle headStyle = createHeadStyle(workbook); // 生成头部样式
HSSFCellStyle commonDataStyle = createCommonDataStyle(workbook); // 生成一般数据样式
HSSFCellStyle numStyle = createNumStyle(workbook); //生成数字类型保留两位小数样式
HSSFCellStyle sumRowStyle = createSumRowStyle(workbook); //生成合计行样式 if(headers == null || headers.length <= 0){
return;
} HSSFRow row = sheet.createRow(0); // 产生表格标题行
for (int i = 0; i < headers.length; i++) {
HSSFCell cell = row.createCell(i);
cell.setCellStyle(headStyle);
HSSFRichTextString text = new HSSFRichTextString(headers[i]);
cell.setCellValue(text);
} if(isSortDataSet && mergeBasis != null && mergeBasis.length > 0){ //是否排序数据
Collections.sort(dataset, new Comparator<String[]>() {
public int compare(String[] o1, String[] o2) {
String s1 = "";
String s2 = "";
for(int i = 0 ; i < mergeBasis.length ; i++){
s1+=(o1[mergeBasis[i].intValue()]+Character.valueOf((char)127).toString());
s2+=(o2[mergeBasis[i].intValue()]+Character.valueOf((char)127).toString());
}
if(timeCells != null && timeCells.length > 0){
for(int i = 0 ; i < timeCells.length ; i++){
s1+= o1[timeCells[i].intValue()];
s2+= o2[timeCells[i].intValue()];
}
}
if(s1.compareTo(s2) < 0){
return -1;
}else if(s1.compareTo(s2) == 0){
return 0;
}else{
return 1;
}
}
});
}
// 遍历集合数据,产生数据行
Iterator<String[]> it = dataset.iterator();
int index = 0;
while (it.hasNext()) {
index++;
row = sheet.createRow(index);
String[] dataSources = it.next() ;
for (int i = 0; i < dataSources.length; i++) {
HSSFCell cell = row.createCell(i);
cell.setCellStyle(commonDataStyle);
cell.setCellValue(dataSources[i]);
}
}
try {
if(mergeBasis != null && mergeBasis.length > 0 && mergeCells != null && mergeCells.length > 0){
for(int i = 0 ; i < mergeCells.length ; i++){
mergedRegion(sheet,mergeCells[i],1,sheet.getLastRowNum(),workbook,mergeBasis);
}
}
if(sumCells != null && sumCells.length > 0){
createSumRow(sheet, row, headers, sumCells, sumRowStyle, numStyle);
}
workbook.write(out);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
} /**
* 创建合计行
* @param sheet
* @param row
* @param headers
* @param sumCells
* @param sumRowStyle
* @param numStyle
*/
private static void createSumRow(HSSFSheet sheet , HSSFRow row , final String[] headers, final Integer[] sumCells , HSSFCellStyle sumRowStyle,HSSFCellStyle numStyle){
row=sheet.createRow(sheet.getLastRowNum()+1);
for (int i = 0; i < headers.length; i++) {
HSSFCell cell = row.createCell(i);
cell.setCellStyle(sumRowStyle);
}
for(int i = 1 ; i < sheet.getLastRowNum() ; i++){
for(int j = 0 ; j < sumCells.length ; j++){
sheet.getRow(i).getCell(sumCells[j]).setCellValue(Double.parseDouble(sheet.getRow(i).getCell(sumCells[j]).getStringCellValue()));
sheet.getRow(i).getCell(sumCells[j]).setCellStyle(numStyle);
}
}
HSSFCell sumCell = row.getCell(0);
sumCell.setCellValue("合计:");
String sumFunctionStr = null;
for(int i = 0 ; i < sumCells.length ; i++){
sumFunctionStr = "SUM("+CellReference.convertNumToColString(sumCells[i])+"2:"+CellReference.convertNumToColString(sumCells[i])+sheet.getLastRowNum()+")";
row.getCell(sumCells[i]).setCellFormula(sumFunctionStr);
}
} /**
* 合并单元格
* @param sheet
* @param cellLine
* @param startRow
* @param endRow
* @param workbook
* @param mergeBasis
*/
private static void mergedRegion(HSSFSheet sheet, int cellLine,int startRow, int endRow, HSSFWorkbook workbook, Integer[] mergeBasis) {
HSSFCellStyle style = workbook.createCellStyle(); // 样式对象
style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER); // 垂直
style.setAlignment(HSSFCellStyle.ALIGN_CENTER); // 水平
String s_will = sheet.getRow(startRow).getCell(cellLine).getStringCellValue(); // 获取第一行的数据,以便后面进行比较
int count = 0;
Set<Integer> set = new HashSet<Integer>();
CollectionUtils.addAll(set, mergeBasis);
for (int i = 2; i <= endRow; i++) {
String s_current = sheet.getRow(i).getCell(cellLine).getStringCellValue();
if (s_will.equals(s_current)) {
boolean isMerge = true;
if(!set.contains(cellLine)){//如果不是作为基准列的列 需要所有基准列都相同
for(int j = 0 ; j < mergeBasis.length ; j++){
if(!sheet.getRow(i).getCell(mergeBasis[j]).getStringCellValue()
.equals(sheet.getRow(i-1).getCell(mergeBasis[j]).getStringCellValue())){
isMerge = false;
}
}
}else{//如果作为基准列的列 只需要比较列号比本列号小的列相同
for(int j = 0 ; j < mergeBasis.length && mergeBasis[j] < cellLine ; j++){
if(!sheet.getRow(i).getCell(mergeBasis[j]).getStringCellValue()
.equals(sheet.getRow(i-1).getCell(mergeBasis[j]).getStringCellValue())){
isMerge = false;
}
}
}
if(isMerge){
count++;
}else{
sheet.addMergedRegion(new CellRangeAddress( startRow, startRow+count,cellLine , cellLine));
startRow = i;
s_will = s_current;
count = 0;
}
} else {
sheet.addMergedRegion(new CellRangeAddress( startRow, startRow+count,cellLine , cellLine));
startRow = i;
s_will = s_current;
count = 0;
}
if (i == endRow && count > 0) {
sheet.addMergedRegion(new CellRangeAddress(startRow,startRow+count ,cellLine , cellLine));
}
}
} /**
* 标题单元格样式
* @param workbook
* @return
*/
private static HSSFCellStyle createHeadStyle(HSSFWorkbook workbook){
//标题单元格样式
HSSFCellStyle headStyle = workbook.createCellStyle();
headStyle.setFillForegroundColor(HSSFColor.SKY_BLUE.index);
headStyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
headStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN);
headStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);
headStyle.setBorderRight(HSSFCellStyle.BORDER_THIN);
headStyle.setBorderTop(HSSFCellStyle.BORDER_THIN);
headStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);
//标题单元格字体
HSSFFont headFont = workbook.createFont();
headFont.setColor(HSSFColor.VIOLET.index);
headFont.setFontHeightInPoints((short) 12);
headFont.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
// 把字体应用到当前的样式
headStyle.setFont(headFont);
return headStyle;
} /**
* 合计行单元格样式
* @param workbook
* @return
*/
private static HSSFCellStyle createSumRowStyle(HSSFWorkbook workbook){
//合计行单元格样式
HSSFCellStyle sumRowStyle = workbook.createCellStyle();
sumRowStyle.setFillForegroundColor(HSSFColor.SKY_BLUE.index);
sumRowStyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
sumRowStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN);
sumRowStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);
sumRowStyle.setBorderRight(HSSFCellStyle.BORDER_THIN);
sumRowStyle.setBorderTop(HSSFCellStyle.BORDER_THIN);
sumRowStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);
sumRowStyle.setDataFormat(HSSFDataFormat.getBuiltinFormat("#,##0.00"));
//合计行单元格字体
HSSFFont sumRowFont = workbook.createFont();
sumRowFont.setColor(HSSFColor.VIOLET.index);
sumRowFont.setFontHeightInPoints((short) 12);
sumRowFont.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
// 把字体应用到当前的样式
sumRowStyle.setFont(sumRowFont);
return sumRowStyle;
} /**
* 普通数据单元格样式
* @param workbook
* @return
*/
private static HSSFCellStyle createCommonDataStyle(HSSFWorkbook workbook){
//普通数据单元格样式
HSSFCellStyle commonDataStyle = workbook.createCellStyle();
commonDataStyle.setFillForegroundColor(HSSFColor.LIGHT_YELLOW.index);
commonDataStyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
commonDataStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN);
commonDataStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);
commonDataStyle.setBorderRight(HSSFCellStyle.BORDER_THIN);
commonDataStyle.setBorderTop(HSSFCellStyle.BORDER_THIN);
commonDataStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);
commonDataStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
//普通数据单元格字体
HSSFFont commonDataFont = workbook.createFont();
commonDataFont.setBoldweight(HSSFFont.BOLDWEIGHT_NORMAL);
//把字体应用到当前的样式
commonDataStyle.setFont(commonDataFont);
return commonDataStyle;
} /**
* 自定义保留两位小数数字单元格格式
* @param workbook
* @return
*/
private static HSSFCellStyle createNumStyle(HSSFWorkbook workbook){
//自定义保留两位小数数字单元格格式
HSSFCellStyle numStyle = workbook.createCellStyle();
numStyle.setFillForegroundColor(HSSFColor.LIGHT_YELLOW.index);
numStyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
numStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN);
numStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);
numStyle.setBorderRight(HSSFCellStyle.BORDER_THIN);
numStyle.setBorderTop(HSSFCellStyle.BORDER_THIN);
numStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);
numStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
numStyle.setDataFormat(HSSFDataFormat.getBuiltinFormat("#,##0.00"));
//自定义保留两位小数数字单元格字体
HSSFFont numFont = workbook.createFont();
numFont.setBoldweight(HSSFFont.BOLDWEIGHT_NORMAL);
//把字体应用到当前的样式
numStyle.setFont(numFont);
return numStyle;
} public static void main(String[] args) {
String[] headers = { "大区", "部门", "金额", "数量", "日期" };
List<String[]> dataset = new ArrayList<String[]>();
dataset.add(new String[] {"华东", "部门3", "35", "1", "2015-01-01"});
dataset.add(new String[] {"华北", "部门1", "20", "1", "2015-01-02"});
dataset.add(new String[] {"华北", "部门2", "25", "1", "2015-01-03"});
dataset.add(new String[] {"华北", "部门5", "25", "1", "2015-01-04"});
dataset.add(new String[] {"华南", "部门1", "15", "1", "2015-01-05"});
dataset.add(new String[] {"华北", "部门3", "30", "1", "2015-01-06"});
dataset.add(new String[] {"华北", "部门3", "30", "1", "2015-01-07"});
dataset.add(new String[] {"华东", "部门1", "25", "1", "2015-01-08"});
dataset.add(new String[] {"华南", "部门4", "30", "1", "2015-01-09"});
dataset.add(new String[] {"华东", "部门2", "25", "1", "2015-01-10"});
dataset.add(new String[] {"华东", "部门2", "25", "1", "2015-01-11"});
dataset.add(new String[] {"华东", "部门3", "35", "1", "2015-01-12"});
dataset.add(new String[] {"华南", "部门1", "15", "1", "2015-01-13"});
dataset.add(new String[] {"华北", "部门6", "20", "1", "2015-01-14"});
dataset.add(new String[] {"华南", "部门2", "25", "1", "2015-01-15"});
dataset.add(new String[] {"华南", "部门2", "25", "1", "2015-01-16"});
dataset.add(new String[] {"华东", "部门1", "25", "1", "2015-01-17"});
dataset.add(new String[] {"华南", "部门8", "30", "1", "2015-01-18"});
dataset.add(new String[] {"华东", "部门2", "35", "1", "2015-01-01"});
dataset.add(new String[] {"华北", "部门1", "20", "1", "2015-01-02"});
dataset.add(new String[] {"华北", "部门11", "25", "1", "2015-01-03"});
dataset.add(new String[] {"华北", "部门2", "25", "1", "2015-01-04"});
dataset.add(new String[] {"华南", "部门1", "15", "1", "2015-01-05"});
dataset.add(new String[] {"华北", "部门4", "30", "1", "2015-01-06"});
dataset.add(new String[] {"华北", "部门3", "30", "1", "2015-01-07"});
dataset.add(new String[] {"华东", "部门9", "25", "1", "2015-01-08"});
dataset.add(new String[] {"华南", "部门3", "30", "1", "2015-01-09"});
dataset.add(new String[] {"华东", "部门12", "25", "1", "2015-01-10"});
dataset.add(new String[] {"华东", "部门2", "25", "1", "2015-01-11"});
dataset.add(new String[] {"华东", "部门12", "35", "1", "2015-01-12"});
dataset.add(new String[] {"华南", "部门1", "15", "1", "2015-01-13"});
dataset.add(new String[] {"华北", "部门11", "20", "1", "2015-01-14"});
dataset.add(new String[] {"华南", "部门21", "25", "1", "2015-01-15"});
dataset.add(new String[] {"华南", "部门2", "25", "1", "2015-01-16"});
dataset.add(new String[] {"华东", "部门15", "25", "1", "2015-01-17"});
dataset.add(new String[] {"华南", "部门3", "30", "1", "2015-01-18"});
dataset.add(new String[] {"华东", "部门3", "35", "1", "2015-01-01"});
dataset.add(new String[] {"华北", "部门17", "20", "1", "2015-01-02"});
dataset.add(new String[] {"华北", "部门22", "25", "1", "2015-01-03"});
dataset.add(new String[] {"华北", "部门2", "25", "1", "2015-01-04"});
dataset.add(new String[] {"华南", "部门1", "15", "1", "2015-01-05"});
dataset.add(new String[] {"华北", "部门2", "30", "1", "2015-01-06"});
dataset.add(new String[] {"华北", "部门3", "30", "1", "2015-01-07"});
dataset.add(new String[] {"华东", "部门1", "25", "1", "2015-01-08"});
dataset.add(new String[] {"华南", "部门8", "30", "1", "2015-01-09"});
dataset.add(new String[] {"华东", "部门2", "25", "1", "2015-01-10"});
dataset.add(new String[] {"华东", "部门2", "25", "1", "2015-01-11"});
dataset.add(new String[] {"华东", "部门3", "35", "1", "2015-01-12"});
dataset.add(new String[] {"华南", "部门7", "15", "1", "2015-01-13"});
dataset.add(new String[] {"华北", "部门1", "20", "1", "2015-01-14"});
dataset.add(new String[] {"华南", "部门2", "25", "1", "2015-01-15"});
dataset.add(new String[] {"华南", "部门2", "25", "1", "2015-01-16"});
dataset.add(new String[] {"华东", "部门9", "25", "1", "2015-01-17"});
dataset.add(new String[] {"华南", "部门3", "30", "1", "2015-01-18"});
try {
OutputStream out = new FileOutputStream("E://a.xls");
ExcelUtil_Extend.createExcelMerge("测试.xls", headers, dataset, true, out, new Integer[]{0,1}, new Integer[]{0,1}, new Integer[]{2,3}, new Integer[]{4});
out.close();
JOptionPane.showMessageDialog(null, "导出成功!");
System.out.println("excel导出成功!");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}

导出excel带合并单元格方法的Demo的更多相关文章

  1. WPF 导出Excel(合并单元格)

    WPF 导出Excel(合并单元格) DataTable 导出Excel(导出想要的列,不想要的去掉) ,B1,B2,B3,B4,B5} MisroSoft.Office.Interop.Excel. ...

  2. 使用npoi导入Excel - 带合并单元格--附代码

    之前我们在使用npoi导入excel表格的时候,往往会遇见那种带有合并单元格的数据在导入的时候出现合并为空的问题, 也就是只有第一条有数据,其余均为空白.在网上翻了半天也没有找到合适的解决方案,最后还 ...

  3. 转:jxl导出excel(合并单元格)

    Demo 代码如下: import java.io.*; import jxl.*; import jxl.format.UnderlineStyle; import jxl.write.*; pub ...

  4. 用NPOI创建Excel、合并单元格、设置单元格样式、边框的方法

    本篇文章小编为大家介绍,用NPOI创建Excel.合并单元格.设置单元格样式.边框的方法.需要的朋友参考下 今天在做项目中,遇到使用代码生成具有一定样式的Excel,找了很多资料,最后终于解决了,Ex ...

  5. 前端Excel表格导入导出,包括合并单元格,表格自定义样式等

    表格数据导入 读取导入Excel表格数据这里采用的是 xlsx 插件 npm i xlsx 读取excel需要通过 XLSX.read(data, {type: type}) 方法来实现,返回一个叫W ...

  6. POI导出复杂Excel,合并单元格(2)

    /** * 导出excel (HSSFWorkbook) */ @GetMapping("/testExport") public void testExport1(HttpSer ...

  7. POI导出复杂Excel,合并单元格(1)

    /** * 导出复杂excel 合并单元格 (HSSFWorkbook) */ @GetMapping("/testHSSFWorkbook.do") public void te ...

  8. .net读取Excel转datatable、.net读取的Excel存在合并单元格并且转成datatable

    项目中经常会遇到Excel导入数据,Excel的模板会可能是存在合并单元格的,模板如下图所示 读取时需要填充合并单元格的值,转成datatable单元格值时,填充合并单元格的值,如下图所示: 合并单元 ...

  9. poi excel设置合并单元格边框格式

    版本3.17 //设置合并单元格的边框 public static void setBorderForMergeCell(BorderStyle style,int color, CellRangeA ...

随机推荐

  1. Spring系列之aAOP AOP是什么?+xml方式实现aop+注解方式实现aop

    Spring系列之aop aop是什么?+xml方式实现aop+注解方式实现aop 什么是AOP? AOP为Aspect Oriented Programming 的缩写,意识为面向切面的编程,是通过 ...

  2. luogu 3376 最小费用最大流 模板

    类似EK算法,只是将bfs改成spfa,求最小花费. 为什么可以呢,加入1-3-7是一条路,求出一个流量为40,那么40*f[1]+40*f[2]+40*f[3],f[1]是第一条路的单位费用,f[2 ...

  3. html 背景花瓣特效--1

    html背景樱花可以用js添加,将<script>标签复制到<body>标签下就可以,javascript脚本点击 <!DOCTYPE html> <html ...

  4. 64位系统 system32 和 syswow64

    \Windows\SysWOW64  文件夹下存放32位的库和应用程序 (WOW64 == Windows on Windows 64 bit ) \Windows\System32  文件夹下存放6 ...

  5. C++实现串口通信问题(与Arduino)

    参考1(已验证稍加修改可与Arduino通信):https://blog.csdn.net/qq_36106219/article/details/81701368 参考2(比较全,main函数需要自 ...

  6. ISP-OB, pedestal 以及ISP概述

    网上的直接参考资料 1. https://zhuanlan.zhihu.com/p/36896537 2. https://blog.csdn.net/m0_38049850/article/deta ...

  7. 状压DP——【蜀传之单刀赴会】

    某王   老师今天考了一套三国题,AK了...就挑一道最恶心的题来写一写吧. 题目描述: [题目背景] 公元215年,刘备取益州,孙权令诸葛瑾找刘备索要荆州.刘备不答应,孙权极为恼恨,便派吕蒙率军取长 ...

  8. Git本地已有项目关联远程仓库

    情况: 本地已有项目 远程有个仓库 目的: 本地项目关联远程仓库 首先要把本地项目变成git管理的,也就是建立一个本地仓库,可以在项目目录下面使用git init命令初始化仓库,初始化成功之后会在仓库 ...

  9. EntityFramwork基础用法

    一.EntityFramework(简称"EF")是什么? 在.NET3.5之前,我们经常编写ADO.NET代码或通过封装好的数据库访问层来与数据库进行交互,进行CRUD操作.这种 ...

  10. mycat 1.6实现读写分离

    使用mysql的root账号执行mysql>grant all privileges on *.* to mycatuser@% identified by '123456';mysql> ...