|
|
@@ -1,16 +1,27 @@
|
|
|
package com.minpay.common.util;
|
|
|
|
|
|
+import org.apache.poi.ss.util.CellRangeAddress;
|
|
|
import org.apache.poi.xssf.usermodel.*;
|
|
|
|
|
|
import java.util.ArrayList;
|
|
|
import java.util.Collections;
|
|
|
import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
|
|
|
/**
|
|
|
*
|
|
|
*/
|
|
|
public class ExportUtils {
|
|
|
public final static String COLUMNS_SEPARATOR = "#";//分割符
|
|
|
+ //03Excel:单个sheet可以保存:行(65536)*列(256)=16777216个数据。
|
|
|
+ //07Excel:单个sheet可以保存:行(1048576)*列(16384)=17179869184个数据。
|
|
|
+ public final static int EXCEL_DATA_SIZE = 65000;
|
|
|
+ private static XSSFWorkbook xwb ;
|
|
|
+ private static XSSFSheet sheet;
|
|
|
+ private static XSSFRow row;
|
|
|
+ private static XSSFCell cell ;
|
|
|
+ private static XSSFCellStyle cellStyle;
|
|
|
+ private static XSSFFont fontStyle;
|
|
|
/**
|
|
|
* 描述列样式
|
|
|
* @param wb
|
|
|
@@ -26,13 +37,13 @@ public class ExportUtils {
|
|
|
style.setBorderRight(XSSFCellStyle.BORDER_THIN);
|
|
|
style.setBorderTop(XSSFCellStyle.BORDER_THIN);
|
|
|
style.setAlignment(XSSFCellStyle.ALIGN_LEFT);
|
|
|
+ style.setVerticalAlignment(XSSFCellStyle.VERTICAL_CENTER);
|
|
|
// 生成一个字体
|
|
|
XSSFFont font = wb.createFont();
|
|
|
font.setBoldweight(XSSFFont.BOLDWEIGHT_BOLD);
|
|
|
font.setFontName("宋体");
|
|
|
font.setColor(new XSSFColor(java.awt.Color.RED));
|
|
|
font.setFontHeightInPoints((short) 12);
|
|
|
- // 把字体应用到当前的样式
|
|
|
style.setFont(font);
|
|
|
return style;
|
|
|
}
|
|
|
@@ -53,13 +64,13 @@ public class ExportUtils {
|
|
|
style.setBorderRight(XSSFCellStyle.BORDER_THIN);
|
|
|
style.setBorderTop(XSSFCellStyle.BORDER_THIN);
|
|
|
style.setAlignment(XSSFCellStyle.ALIGN_CENTER);
|
|
|
+// style.setVerticalAlignment(XSSFCellStyle.VERTICAL_CENTER);
|
|
|
// 生成一个字体
|
|
|
XSSFFont font = wb.createFont();
|
|
|
font.setBoldweight(XSSFFont.BOLDWEIGHT_BOLD);
|
|
|
font.setFontName("宋体");
|
|
|
font.setColor(new XSSFColor(java.awt.Color.BLACK));
|
|
|
font.setFontHeightInPoints((short) 11);
|
|
|
- // 把字体应用到当前的样式
|
|
|
style.setFont(font);
|
|
|
return style;
|
|
|
}
|
|
|
@@ -71,23 +82,27 @@ public class ExportUtils {
|
|
|
*/
|
|
|
public static XSSFCellStyle getTextCellStyle(XSSFWorkbook wb) {
|
|
|
// 生成并设置另一个样式
|
|
|
- XSSFCellStyle style2 = wb.createCellStyle();
|
|
|
- style2.setFillForegroundColor(new XSSFColor(java.awt.Color.WHITE));
|
|
|
- style2.setFillPattern(XSSFCellStyle.SOLID_FOREGROUND);
|
|
|
- style2.setBorderBottom(XSSFCellStyle.BORDER_THIN);
|
|
|
- style2.setBorderLeft(XSSFCellStyle.BORDER_THIN);
|
|
|
- style2.setBorderRight(XSSFCellStyle.BORDER_THIN);
|
|
|
- style2.setBorderTop(XSSFCellStyle.BORDER_THIN);
|
|
|
- style2.setAlignment(XSSFCellStyle.ALIGN_CENTER);
|
|
|
- style2.setVerticalAlignment(XSSFCellStyle.VERTICAL_CENTER);
|
|
|
- // 生成另一个字体
|
|
|
+ XSSFCellStyle style = wb.createCellStyle();
|
|
|
+ style.setFillForegroundColor(new XSSFColor(java.awt.Color.WHITE));
|
|
|
+ style.setFillPattern(XSSFCellStyle.SOLID_FOREGROUND);
|
|
|
+ style.setBorderBottom(XSSFCellStyle.BORDER_THIN);
|
|
|
+ style.setBorderLeft(XSSFCellStyle.BORDER_THIN);
|
|
|
+ style.setBorderRight(XSSFCellStyle.BORDER_THIN);
|
|
|
+ style.setBorderTop(XSSFCellStyle.BORDER_THIN);
|
|
|
+ style.setAlignment(XSSFCellStyle.ALIGN_CENTER);
|
|
|
+ style.setVerticalAlignment(XSSFCellStyle.VERTICAL_CENTER);
|
|
|
XSSFFont font2 = wb.createFont();
|
|
|
font2.setBoldweight(XSSFFont.BOLDWEIGHT_NORMAL);
|
|
|
- // 把字体应用到当前的样式
|
|
|
- style2.setFont(font2);
|
|
|
- return style2;
|
|
|
+ style.setFont(font2);
|
|
|
+ return style;
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 重组表头数据
|
|
|
+ * @param titleArray
|
|
|
+ * @param manyTitle
|
|
|
+ * @return
|
|
|
+ */
|
|
|
public static String[] autocomplete(String[] titleArray, int manyTitle) {
|
|
|
for(int i = 0; i< titleArray.length; i++) {
|
|
|
titleArray[i] = completeStr(titleArray[i], manyTitle - titleArray[i].split(COLUMNS_SEPARATOR).length);
|
|
|
@@ -101,22 +116,158 @@ public class ExportUtils {
|
|
|
col = col.split(COLUMNS_SEPARATOR)[0] + COLUMNS_SEPARATOR + col;
|
|
|
return completeStr(col, --count);
|
|
|
}
|
|
|
+ /**
|
|
|
+ * 创建sheet
|
|
|
+ * @param wb 工作簿
|
|
|
+ * @param sheetIndex sheet页下标
|
|
|
+ * @param sheetName sheet页名字
|
|
|
+ * @param titleArray 标题数组
|
|
|
+ * @param fieldArray 字段数组
|
|
|
+ * @param descStr
|
|
|
+ * @param list
|
|
|
+ * @param map
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public static int XlzgzCreateSheet(XSSFWorkbook wb, int sheetIndex, String sheetName, String[] titleArray, String[] fieldArray,
|
|
|
+ String descStr, List<Map<String, String>> list, Map<String, String> map){
|
|
|
+ xwb = wb;
|
|
|
+ //样式
|
|
|
+ XSSFCellStyle textCellStyle = getTextCellStyle(xwb);
|
|
|
+ XSSFCellStyle titleCellStyle = getTitleCellStyle(xwb);
|
|
|
+ XSSFCellStyle descCellStyle= getDescCellStyle(xwb);
|
|
|
+ //计算
|
|
|
+ int datalist = 0;
|
|
|
+ int rowLock = 0;
|
|
|
+ if(list != null){
|
|
|
+ datalist = list.size();
|
|
|
+ }
|
|
|
+ int avg = datalist/EXCEL_DATA_SIZE;
|
|
|
+ int sy = datalist%EXCEL_DATA_SIZE;
|
|
|
+ int favg = avg ;
|
|
|
+ if(sy==0&&avg!=0){
|
|
|
|
|
|
+ } else{
|
|
|
+ avg+=1;
|
|
|
+ }
|
|
|
+ //每页放EXCEL_2003_DATA_SIZE条数据
|
|
|
+ for (int ii = 0; ii < avg; ii++) {
|
|
|
+ String name = "";
|
|
|
+ if((favg==1 && sy==0)||(favg==0)){
|
|
|
+ name = sheetName ;
|
|
|
+ }else{
|
|
|
+ name = sheetName+"-sheet"+(ii+1) ;
|
|
|
+ }
|
|
|
+ sheet = wb.createSheet(name);
|
|
|
+ int rowIndex = 0;//当前行号
|
|
|
+ String title = StringUtil.ObjectToString(map.get("title"));
|
|
|
+ if(!"".equals(title)){//标题行
|
|
|
+ row = sheet.createRow((int) rowIndex);// 行数从0开始
|
|
|
+ row.setHeightInPoints(30);//设置行的高度
|
|
|
+ XSSFCell celldesc = row.createCell(0);
|
|
|
+ sheet.addMergedRegion(new CellRangeAddress(0,0,0,titleArray.length - 1));//合并单元格
|
|
|
+ celldesc.setCellValue(StringUtil.ObjectToString(title));
|
|
|
+ celldesc.setCellStyle(descCellStyle);
|
|
|
+ rowIndex ++;
|
|
|
+ }
|
|
|
+ if(!"".equals(descStr)){//描述行
|
|
|
+ //添加描述行
|
|
|
+ row = sheet.createRow((int) rowIndex);// 行数从0开始
|
|
|
+ row.setHeightInPoints(30);//设置行的高度
|
|
|
+ XSSFCell celldesc = row.createCell(0);
|
|
|
+ sheet.addMergedRegion(new CellRangeAddress(0,0,0,titleArray.length - 1));//合并单元格
|
|
|
+ celldesc.setCellValue(StringUtil.ObjectToString(descStr));
|
|
|
+ celldesc.setCellStyle(descCellStyle);
|
|
|
+ rowIndex++;
|
|
|
+ }
|
|
|
+ int manyTitle = 1;// 表头默认一行
|
|
|
+ if(titleArray.length > 0){//标题行
|
|
|
+ if (titleArray != null && titleArray.length > 0){
|
|
|
+ for (int i = 0; i < titleArray.length; i++) {
|
|
|
+ for (String col : titleArray) {
|
|
|
+ String[] colTitles = col.split(ExportUtils.COLUMNS_SEPARATOR);
|
|
|
+ manyTitle = Math.max(manyTitle,colTitles.length);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //重组表头
|
|
|
+ titleArray = ExportUtils.autocomplete(titleArray, manyTitle);
|
|
|
+ for (int j = 0; j < manyTitle; j++) {
|
|
|
+ row = sheet.createRow((int) rowIndex);
|
|
|
+ // 表头数据填充
|
|
|
+ for(int i = 0; i < titleArray.length; i++) {
|
|
|
+ cell = row.createCell(i );// 0号位被序号占用,所以需+1
|
|
|
+ cell.setCellValue(titleArray[i].split("#")[j]);
|
|
|
+ cell.setCellStyle(titleCellStyle);
|
|
|
+ sheet.setColumnWidth(i, 30 * 256);
|
|
|
+ }
|
|
|
+ rowIndex ++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ rowLock = rowIndex;
|
|
|
+ sheet.createFreezePane(0, rowLock, 0, 0);
|
|
|
+ int rowLength = 0; //导出excel的总行数
|
|
|
+ if(ii < favg){
|
|
|
+ rowLength = EXCEL_DATA_SIZE; //导出excel的总行数
|
|
|
+ }else{
|
|
|
+ rowLength = sy; //导出excel的总行数
|
|
|
+ }
|
|
|
+ //合并表头
|
|
|
+ ExportUtils.titleMerge(sheet, rowIndex - manyTitle, titleArray, manyTitle);
|
|
|
+ //数据列
|
|
|
+ for (int i = 0; i < rowLength; i++) {
|
|
|
+ //创建行
|
|
|
+ row = sheet.createRow((int) rowIndex);
|
|
|
+ Map<String,String> temp = list.get( ii * EXCEL_DATA_SIZE + i);
|
|
|
+ for (int j = 0; j < fieldArray.length; j++) {
|
|
|
+ cell = row.createCell(j);
|
|
|
+ cell.setCellValue(StringUtil.ObjectToString(temp.get(fieldArray[j])));
|
|
|
+ cell.setCellStyle(textCellStyle);
|
|
|
+ }
|
|
|
+ rowIndex ++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
/**
|
|
|
* 表头数据合并
|
|
|
* @param sheet
|
|
|
- * @param coltitleIndex 列数
|
|
|
- * @param colTitles 标题行
|
|
|
- * @param num 行索引
|
|
|
+ * @param coltitleIndex 表头起始行
|
|
|
+ * @param colTitles 标题列
|
|
|
+ * @param num 表头占几行
|
|
|
*/
|
|
|
public static void titleMerge(XSSFSheet sheet, int coltitleIndex, String[] colTitles, int num) {
|
|
|
+ List<int[]> melist = new ArrayList<>();
|
|
|
for(int i = 0; i < num; i++) {
|
|
|
String preVal = "";
|
|
|
int columnIndex = 0;
|
|
|
for(int j = 0; j < colTitles.length; j++) {
|
|
|
columnIndex++;
|
|
|
preVal = colTitles[j].split(COLUMNS_SEPARATOR)[i];
|
|
|
- String columnVal = colTitles[j + 1].split(COLUMNS_SEPARATOR)[i];
|
|
|
+ String columnVal = "";
|
|
|
+ try {
|
|
|
+ columnVal = colTitles[j + 1].split(COLUMNS_SEPARATOR)[i];
|
|
|
+ } catch (Exception e1) {
|
|
|
+ List<Integer> list = new ArrayList<Integer>();
|
|
|
+ for(int m = j - columnIndex + 1; m <= j; m++) {
|
|
|
+ int bottom = 0;
|
|
|
+ for(int k = i + 1; k <= num; k++) {
|
|
|
+ String nextRowVal = "";
|
|
|
+ try {
|
|
|
+ nextRowVal = colTitles[m].split(COLUMNS_SEPARATOR)[k];
|
|
|
+ } catch (Exception e) {
|
|
|
+ list.add(bottom);
|
|
|
+ }
|
|
|
+ if(!"".equals(nextRowVal) && !preVal.equals(nextRowVal)) {
|
|
|
+ list.add(bottom);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ bottom++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ Collections.sort(list); //从小到大
|
|
|
+ melist.add(new int[]{j - columnIndex + 1,coltitleIndex + i, j, coltitleIndex + i + list.get(0)});
|
|
|
+ columnIndex = 0;
|
|
|
+ }
|
|
|
if(!"".equals(columnVal) && !preVal.equals(columnVal)) {
|
|
|
List<Integer> list = new ArrayList<Integer>();
|
|
|
for(int m = j - columnIndex + 1; m <= j; m++) {
|
|
|
@@ -136,10 +287,19 @@ public class ExportUtils {
|
|
|
}
|
|
|
}
|
|
|
Collections.sort(list); //从小到大
|
|
|
+ melist.add(new int[]{j - columnIndex + 1,coltitleIndex + i, j, coltitleIndex + i + list.get(0)});
|
|
|
columnIndex = 0;
|
|
|
}
|
|
|
preVal = columnVal;
|
|
|
}
|
|
|
}
|
|
|
+ if ( melist!= null && melist.size() > 0 ){
|
|
|
+ for (int i = 0; i < melist.size(); i++) {
|
|
|
+ int[] mergeCell = melist.get(i);
|
|
|
+ //合并单元格
|
|
|
+ sheet.addMergedRegion(new CellRangeAddress(mergeCell[1],mergeCell[3],mergeCell[0],mergeCell[2]));//合并单元格
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
}
|