`
lizhenbin2010
  • 浏览: 99683 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

poi创建Excel设计

    博客分类:
  • J2se
阅读更多

      电商商务,目前为止,做网站后台管理系统对到处数据的要求不是很高,反正自己公司内部用的嘛,能拉出来就行了,尽量简单。但是随着业务的发展,供应链系统出来了,涉及到订单,采购,库存,退款退货,财务等模块的集成。系统的生成Excel的业务越来越多,于是乎每个人都自己copy一段前人实现的代码,直接修改修改就生成一个Excel了。

       这个操作方法,刚刚系统还小的时候,也没有什么关系,来回就那么点代码,可是当系统复杂了,导出的业务多了,每次代码review都看到一大段相同的代码,很不爽。于是乎写成公用类也就成为必然了。

 

下面是我设计生成Excel文件的设计:

一、生成一个文本Excel的抽象接口是要有如下几个方法:

package com.hqb360.common.excel;

import javax.servlet.http.HttpServletResponse;
import java.util.List;

/**
 * 功能描述: 创建Excel接口
 *
 * @author: Zhenbin.Li
 * Date: 13-11-19 Time:下午12:42
 */
public interface ExportExcelAware<T> {

    /**
     * 创建生成Excel文件
     *
     * <p>需要实现接口中的每一个方法, 接口中的方法都对应生成Excel的一个功能</p>     *
     * @param response HttpServletResponse
     * @param exportList 输出到Excel表格list
     */
    public void create(HttpServletResponse response, List<T> exportList);

    /**
     * 初始化Excel报表标题
     *
     * @return 报表标题
     */
    public String initTitle();

    /**
     * 初始化Excel文件名称
     *
     * @return
     */
    public String initFileName();

    /**
     * 初始化Excel Sheet名称
     *
     * @return
     */
    public String initSheetName();

    /**
     * 获得报表列头标题
     *
     * 1、如果是一行列头标题,则可以通过如下代码实现:
     * 		String[][] colTitles = { { "列1", "列2", "列3" } }
     * 		return colTitles;
     * 2、如果是二行列头标题,则可以通过如下代码实现:
     * 		String[][] colTitles = { { "行1列1", "行1列2", null, "行1列4" },
     * 								 { null, "行2列2", "行2列3", "行2列4" }};
     * 		return colTitles;
     * 	  将显示的列标题实际效果为:
     * 	   <table border="1">
     * 			<tr align="center">
     * 				<td rowspan="2">行1列1</td>
     * 				<td colspan="2">行1列2</td>
     * 				<td>行1列4</td>
     * 			</tr>
     * 			<tr align="center">
     * 				<td>行2列2</td>
     * 				<td>行2列3</td>
     * 				<td>行2列4</td>
     * 			</tr>
     * 		</table>
     * @return 列头标题
     */
    public String[][] initColTitles();

    /**
     * 处理Excel报表展示的数据
     *
     * @param exportList 输出到Excel list集合
     * @return 1、列表,List(String[]);
     *         2、有合并一列的数据,Map(List(String[]));
     *         3、有合并两列的数据,Map(Map(List(String[])))。
     */
    public Object handleBodyData(List<T> exportList);

    /**
     * 初始化Excel报表展示的样式
     *
     * @return 列表,Map(int,String );
     */
    public Object initRowStyle();

    /**
     * 初始化Excel列宽
     *
     * @return 列宽
     */
    public int[] initColumnWidth();

    /**
     * 初始化Excel报表备注信息
     *
     * @return 报表备注信息
     */
    public String[] initRemark();

}

 

 二、抽象实现

package com.hqb360.common.excel;

import com.google.common.collect.Maps;
import com.hqb360.common.lang.ArrayUtil;
import com.hqb360.common.lang.DateUtil;
import com.hqb360.common.lang.StringUtil;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 功能描述:创建Excel抽象实现
 *
 * @author: Zhenbin.Li
 * Date: 13-11-19 Time:下午12:44
 */
public abstract class DefaultExportExcelAdapter<T> implements ExportExcelAware<T> {

    /**
     * 文件下载的header key
     */
    private static final String RESOURCE_HEADER_KEY = "Content-Disposition";

    /**
     * 文件下载的contentType
     */
    private static final String RESOURCE_CONTENT_TYPE = "application/octet-stream;charset=UTF-8";

    /**
     * Excel Sheet默认名称
     */
    private static final String DEFAULT_SHEET_NAME = "sheet";

    /**
     * 生成Excel文件Session
     */
    private Map<SessionKey, Object> exportSession = Maps.newHashMap();

    @Override
    public synchronized void create(HttpServletResponse response, List<T> exportList) {

        // 初始化Session
        initSession(response, exportList);

        // 验证必要参数
        validExportSession();

        String sheetName = exportSession.get(SessionKey.SHEET_NAME) == null ?
                DEFAULT_SHEET_NAME : (String) exportSession.get(SessionKey.SHEET_NAME);
        ExportExcelFactory exportExcelFactory = new ExportExcelFactory(sheetName);

        // 表格名称
        StringBuffer titleBuffer = new StringBuffer();
        titleBuffer.append(exportSession.get(SessionKey.TITLE)).append("(导出时间:")
                .append(DateUtil.formatDateTime()).append(")");

        //列头标题
        String[][] colTitles = (String[][]) exportSession.get(SessionKey.COL_TITLES);
        exportExcelFactory.setCols(colTitles[0].length);
        exportExcelFactory.createCaption(titleBuffer.toString());
        exportExcelFactory.createColCaption(colTitles);

        Object bodyData = exportSession.get(SessionKey.BODY_DATA);
        if (bodyData != null) {
            Object rowColor = exportSession.get(SessionKey.ROW_COLOR);
            if (rowColor == null) {
                exportExcelFactory.createBody(bodyData);
            } else {
                exportExcelFactory.createBody(bodyData, rowColor);
            }
        }

        if (exportSession.get(SessionKey.COLUMN_WIDTH) != null) {
            int[] columnWidths = (int[]) exportSession.get(SessionKey.COLUMN_WIDTH);
            if (ArrayUtil.isNotEmpty(columnWidths)) {
                exportExcelFactory.setColumnWidth(columnWidths);
            }
        }

        if (exportSession.get(SessionKey.REMARKS) != null) {
            String[] remarks = (String[]) exportSession.get(SessionKey.REMARKS);
            if (ArrayUtil.isEmpty(remarks)) {
                exportExcelFactory.createRemarks(remarks);
            }
        }

        String excelFileName = initFileName() + ".xls";
        try {
            excelFileName = new String(excelFileName.getBytes("GBK"),"ISO-8859-1");
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException("导出Excel业务, encode文件名称异常, excelFileName=" + excelFileName, e);
        }

        // 写文件
        OutputStream os = null;
        response.reset();

        // 写入下载响应头信息
        writeDownloadResHeader(excelFileName, response);
        try {
            os = response.getOutputStream();
            exportExcelFactory.createFile(response.getOutputStream());
        } catch (IOException e) {
            throw new RuntimeException("导出Excel业务, 生成Excel文件异常", e);
        } finally {
            if (os != null) {
                try {
                    os.close();
                } catch (IOException e) {
                }
            }
        }
    }

    /**
     * Excel标题,继承时必须要实现
     *
     * @return
     */
    @Override
    public abstract String initTitle();

    /**
     * 获取导出Excel文件名称
     *
     * @return
     */
    @Override
    public String initFileName() {
        StringBuffer fileName = new StringBuffer();
        fileName.append(initTitle()).append("(").append(DateUtil.format(new Date(), "yyyyMMddHHmmss")).append(")");
        return fileName.toString();
    }

    @Override
    public String initSheetName() {
        return "sheet";
    }

    /**
     * Excel列属性值,继承时必须要实现
     *
     * @return
     */
    @Override
    public abstract String[][] initColTitles();

    /**
     * 必须要传入值
     *
     * @return
     */
    @Override
    public abstract Object handleBodyData(List<T> exportList);

    /**
     * 设置单元格样式
     *
     * @return
     */
    @Override
    public Object initRowStyle() {
        return null;
    }

    @Override
    public int[] initColumnWidth() {
        return null;
    }

    /**
     * 导出Excel有无备注信息
     *
     * @return
     */
    @Override
    public String[] initRemark() {
        return null;
    }

    /**
     * 写入下载响应头信息
     * <p>声明响应类型和内容类型</p>
     *
     * @param fileName 文件名
     * @param response HTTP响应
     */
    protected static void writeDownloadResHeader(String fileName, HttpServletResponse response) {

        response.addHeader(RESOURCE_HEADER_KEY, "attachment; filename=" + fileName);
        response.setContentType(RESOURCE_CONTENT_TYPE);
    }

    /**
     * Excel文件Session属性值枚举
     */
    protected enum SessionKey {

        RESPONSE,
        BODY_DATA,
        TITLE,
        FILE_NAME,
        COL_TITLES,
        ROW_COLOR,
        REMARKS,
        COLUMN_WIDTH,
        SHEET_NAME
    }

    /**
     * 初始化生成Excel SessionKey
     *
     * @param response
     * @param exportList
     */
    protected void initSession(HttpServletResponse response, List exportList) {

        exportSession.put(SessionKey.RESPONSE, response);
        //报表数据
        exportSession.put(SessionKey.BODY_DATA, handleBodyData(exportList));
        // 报表标题
        exportSession.put(SessionKey.TITLE, initTitle());
        // 文件名称
        exportSession.put(SessionKey.FILE_NAME, initFileName());
        // 列名称
        exportSession.put(SessionKey.COL_TITLES, initColTitles());
        // 行颜色
        exportSession.put(SessionKey.ROW_COLOR, initRowStyle());
        // 备注
        exportSession.put(SessionKey.REMARKS, initRemark());
        // 列宽度
        exportSession.put(SessionKey.COLUMN_WIDTH, initColumnWidth());
        // Sheet名称
        exportSession.put(SessionKey.SHEET_NAME, initSheetName());
    }

    /**
     * 验证Session参数
     */
    protected void validExportSession() {

        if (exportSession.get(SessionKey.TITLE) == null
                || StringUtil.isBlank(String.valueOf(exportSession.get(SessionKey.TITLE)))) {
            throw new RuntimeException("导出Excel业务, Excel表名称为空");
        }

        if (exportSession.get(SessionKey.FILE_NAME) == null
                || StringUtil.isBlank(String.valueOf(exportSession.get(SessionKey.FILE_NAME)))) {
            throw new RuntimeException("导出Excel业务, Excel文件名称为空");
        }

        if (exportSession.get(SessionKey.COL_TITLES) == null
                || ArrayUtil.isEmpty((String[][]) exportSession.get(SessionKey.COL_TITLES))) {
            throw new RuntimeException("导出Excel业务, Excel列属性名称为空");
        }

    }
}

 

 三、测试实现方法,只需要实现抽象方法即可

/**
     * 导出库存列表
     *
     * @param response
     * @return
     */
    @RequestMapping(value = "/invoicing/itemSkusWarehouse/exportItemSkusWarehouse.resource",
            method = RequestMethod.GET)
    public String exportItemSkusWarehouse(HttpServletResponse response) {

        final List<ItemSkuWarehouseExportDo> list = itemSkusWarehouseQueryBiz
                .findItemSkuWarehouseStatisticsForExport().getItemSkuWarehouseExportDos();

        new DefaultExportExcelAdapter<ItemSkuWarehouseExportDo>() {

            @Override
            public String initTitle() {
                return "库存列表";
            }

            @Override
            public String[][] initColTitles() {
                String[][] colTitles = {{"所属类目", "SKU ID", "SKU名称", "良品库", "申购库", "次品库", "赠品库", "寄存库", "成本价", "合计"}};
                return colTitles;
            }

            @Override
            public Object handleBodyData(List<ItemSkuWarehouseExportDo> exportList) {

                List<String[]> exports = Lists.newArrayList();
                if (CollectionUtil.isNotEmpty(exportList)) {
                    for (ItemSkuWarehouseExportDo itemSkuWarehouseExportDo : exportList) {
                        String[] itemSkuWarehouseExportDoArray = new String[initColTitles()[0].length];
                        itemSkuWarehouseExportDoArray[0] = itemSkuWarehouseExportDo.getBelongCatName();
                        itemSkuWarehouseExportDoArray[1] = itemSkuWarehouseExportDo.getSkuId().toString();
                        itemSkuWarehouseExportDoArray[2] = itemSkuWarehouseExportDo.getSkuName();
                        itemSkuWarehouseExportDoArray[3] = itemSkuWarehouseExportDo.getStandardWarehouse().toString();
                        itemSkuWarehouseExportDoArray[4] = itemSkuWarehouseExportDo.getApWarehouse().toString();
                        itemSkuWarehouseExportDoArray[5] = itemSkuWarehouseExportDo.getSubstandardWarehouse().toString();
                        itemSkuWarehouseExportDoArray[6] = itemSkuWarehouseExportDo.getDonationWarehouse().toString();
                        itemSkuWarehouseExportDoArray[7] = itemSkuWarehouseExportDo.getRegisterWarehouse().toString();
                        itemSkuWarehouseExportDoArray[8] = NumberFormatUtil.formatForIgnoreZero(itemSkuWarehouseExportDo.getCostPrice() , 5);
                        itemSkuWarehouseExportDoArray[9] = itemSkuWarehouseExportDo.getCountWarehouse().toString();
                        exports.add(itemSkuWarehouseExportDoArray);
                    }
                }
                return exports;
            }

            @Override
            public String initSheetName() {
                return "库存列表";
            }

            @Override
            public int[] initColumnWidth() {
                int[] columnWidths = {150, 100, 500, 0, 0, 0, 0, 0, 0, 0};
                return columnWidths;
            }

        }.create(response, list);

        return null;
    }

 四、生成Excel工厂实现

package com.hqb360.common.lang.excel;

import com.hqb360.common.lang.StringUtil;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.hssf.util.HSSFColor;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;
import java.util.Map;

/**
 * 功能描述:生成Excel工厂类
 *
 * @author: Zhenbin.Li
 * Date: 13-11-17 Time:上午10:04
 */
public class ExportExcelFactory {

    /** 工作薄 */
    private HSSFWorkbook workbook;

    /** 工作表 */
    private HSSFSheet sheet;

    /** 当前行数 */
    private int currentRow = 0;

    /** 总列数 */
    private int totalCols;

    /** Excel Sheet名称 */
    private final String sheetName;

    /**
     * 默认构造方法
     */
    public ExportExcelFactory(String sheetName) {
        this.sheetName = sheetName;
        workbook = new HSSFWorkbook();
        sheet = workbook.createSheet(getSheetName());
    }

    /**
     * 设置列宽
     *
     * @param columnWidth 列宽信息
     */
    @SuppressWarnings("deprecation")
	public void setColumnWidth(int[] columnWidth) {
        for (int i = 0; i < columnWidth.length; i++) {
            if (columnWidth[i] != 0) {
                if (sheet.getColumnWidth((short) i) != (columnWidth[i] * 37.5)) {
                    sheet.setColumnWidth((short) i, (short) (columnWidth[i] * 37.5));
                }
            }
        }
    }

    /**
     * 设置列数
     *
     * @param cols 列数
     */
    public void setCols(int cols) {
        this.totalCols = cols;
    }

    /**
     * 创建标题
     *
     * @param caption 标题
     */
    public void createCaption(String caption) {
        HSSFFont font = ExportExcelUtil.getFont(workbook, 10, HSSFFont.BOLDWEIGHT_BOLD, HSSFColor.BLACK.index);
        HSSFCellStyle style = ExportExcelUtil.getStyle(workbook, font, HSSFCellStyle.ALIGN_CENTER);

        HSSFRow row = sheet.createRow(currentRow);
        ExportExcelUtil.createCell(row, 0, style, caption);
        for (int i = 1; i < totalCols; i++) {
            ExportExcelUtil.createCell(row, i, style, "");
        }

        ExportExcelUtil.mergeCol(sheet, 0, totalCols - 1, currentRow);
        currentRow++;
    }

    /**
     * 创建一行列标题
     *
     * @param colCaption 一行列标题
     */
    public void createColCaption(String[] colCaption) {
        HSSFFont font = ExportExcelUtil.getFont(workbook, 0, HSSFFont.BOLDWEIGHT_BOLD, HSSFColor.BLACK.index);
        HSSFCellStyle style = ExportExcelUtil.getStyle(workbook, font, HSSFCellStyle.ALIGN_CENTER);

        HSSFRow row = sheet.createRow(currentRow);
        for (int i = 0; i < colCaption.length; i++) {
            ExportExcelUtil.createCell(row, i, style, colCaption[i]);
        }
        currentRow++;
    }

    /**
     * 创建多行列标题
     *
     * @param colCaption 多行列标题
     */
    public void createColCaption(String[][] colCaption) {
        HSSFFont font = ExportExcelUtil.getFont(workbook, 10, HSSFFont.BOLDWEIGHT_BOLD, HSSFColor.BLACK.index);
        HSSFCellStyle style = ExportExcelUtil.getStyle(workbook, font, HSSFCellStyle.ALIGN_CENTER);
        int[][][] spans = getSpans(colCaption);

        for (int i = 0; i < colCaption.length; i++) {
            HSSFRow row = sheet.createRow(currentRow);
            for (int j = 0; j < colCaption[i].length; j++) {
                ExportExcelUtil.createCell(row, j, style, colCaption[i][j]);

                if (spans[i][j] != null) {
                    ExportExcelUtil
                            .mergeRegion(sheet, currentRow, j, currentRow + spans[i][j][0] - 1, j + spans[i][j][1] - 1);
                }
            }
            currentRow++;
        }
    }

    /**
     * 创建EXCEL的主体数据
     *
     * @param data 主体数据,可支持的数据格式有:
     *             1、简单列表 List(String[]);
     *             2、合并一列 Map(List(String[]));
     *             3、合并二列 Map(Map(List(String[]))。
     */
    @SuppressWarnings("rawtypes")
	public void createBody(Object data) {
        int nestedCount = ExportExcelUtil.getNestedCount(data);

        if (nestedCount == 0) {
            createBody((List<String[]>)data);
        } else if (nestedCount == 1) {
            ExportExcelUtil.createOneMapBody(workbook, sheet, (Map) data, currentRow);
        } else if (nestedCount == 2) {
            ExportExcelUtil.createTwoMapBody(workbook, sheet, (Map) data, currentRow);
        } else {
            throw new IllegalArgumentException("不支持的数据格式");
        }
    }

    /**
     * 创建列表的主体数据
     *
     * @param list List(String[])列表数据
     */
    protected void createBody(List<String[]> list) {

        HSSFFont font = ExportExcelUtil.getFont(workbook, 10, HSSFFont.BOLDWEIGHT_NORMAL, HSSFColor.BLACK.index);
        HSSFCellStyle style = ExportExcelUtil.getStyle(workbook, font, HSSFCellStyle.ALIGN_CENTER);

        for (int index = 0; index < list.size(); index++) {
            HSSFRow row = sheet.createRow(currentRow);
            String[] stringArray = list.get(index);
            for (int j = 0; j < stringArray.length; j++) {
                ExportExcelUtil.createCell(row, j, style, stringArray[j]);
            }
            currentRow++;
        }
    }

    /**
     * 创建EXCEL的主体数据
     *
     * @param data 主体数据,可支持的数据格式有:
     *             1、简单列表 List(String[]);
     *             2、合并一列 Map(List(String[]));
     *             3、合并二列 Map(Map(List(String[]))。
     */
	@SuppressWarnings("rawtypes")
	public void createBody(Object data, Object color) {
        int nestedCount = ExportExcelUtil.getNestedCount(data);

        if (nestedCount == 0) {
            ExportExcelUtil.createBodyColor(workbook, sheet, (List) data, (Map) color, currentRow);
        } else if (nestedCount == 1) {
            ExportExcelUtil.createOneMapBody(workbook, sheet, (Map) data, currentRow);
        } else if (nestedCount == 2) {
            ExportExcelUtil.createTwoMapBody(workbook, sheet, (Map) data, currentRow);
        } else {
            throw new IllegalArgumentException("不支持的数据格式");
        }
    }

    /**
     * 创建备注信息
     *
     * @param remarks 备注信息
     */
    public void createRemarks(String[] remarks) {
        HSSFFont font = ExportExcelUtil.getFont(workbook, 10, HSSFFont.BOLDWEIGHT_NORMAL, HSSFColor.RED.index);
        HSSFCellStyle style = ExportExcelUtil.getStyle(workbook, font, HSSFCellStyle.ALIGN_LEFT);

        for (int i = 0; i < remarks.length; i++) {
            HSSFRow row = sheet.createRow(currentRow);
            ExportExcelUtil.createCell(row, 0, style, remarks[i]);

            for (int j = 1; j < totalCols; j++) {
                ExportExcelUtil.createCell(row, j, style, "");
            }

            ExportExcelUtil.mergeCol(sheet, 0, totalCols - 1, currentRow);
            currentRow++;
        }
    }

    /**
     * 创建本地路径的EXCEL文件
     *
     * @param filePath EXCEL文件路径
     */
    public void createFile(String filePath) {
        FileOutputStream out = null;
        try {
            out = new FileOutputStream(filePath);
            workbook.write(out);
        } catch (FileNotFoundException e) {
            throw new RuntimeException("无法创建文件:" + filePath);
        } catch (IOException e) {
            throw new RuntimeException("无法写入文件:" + filePath);
        } finally {
            ExportExcelUtil.closeOutputStream(out);
        }
    }

    /**
     * 把EXCEL文件写入到输出流中
     *
     * @param out 输出流
     * @throws java.io.IOException
     */
    public void createFile(OutputStream out) throws IOException {
        workbook.write(out);
    }


    /**
     * 根据多行报表标题获得一个合并的行列信息
     *
     * @param colTitles 列标题
     * @return 报表标题合并的行列信息:第一维对应标题的行,第二维对应标题的列,
     *         第三维对应标题的合并行和列,已经被合并的行或列则对应的第三维为null。
     */
    public static int[][][] getSpans(String[][] colTitles) {
        int[][][] spans = new int[colTitles.length][][];

        for (int i = 0; i < colTitles.length; i++) {
            spans[i] = new int[colTitles[i].length][];
            for (int j = 0; j < colTitles[i].length; j++) {
                if (colTitles[i][j] != null) {
                    spans[i][j] = new int[2];
                    spans[i][j][0] = ExportExcelUtil.getRowSpan(colTitles, i, j);
                    spans[i][j][1] = ExportExcelUtil.getColSpan(colTitles, i, j);
                }
            }
        }

        return spans;
    }

    /**
     * 获取Excel Sheet名称
     *
     * @return
     */
    public String getSheetName() {
        return sheetName;
    }
}

 

package com.hqb360.common.lang.excel;

import java.io.IOException;
import java.io.OutputStream;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFFont;
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.hssf.util.Region;

/**
 * 功能描述: ExportExcelFactory.java类抽取其方法工具类
 *
 * @author: Zhenbin.Li
 * Date: 13-11-17 Time:上午10:20
 */
@SuppressWarnings("deprecation")
public class ExportExcelUtil {

    /**
     * 创建列表的主体数据
     *
     * @param workbook
     * @param list       List(String[])列表数据
     * @param color
     * @param sheet
     * @param currentRow
     */
    @SuppressWarnings("rawtypes")
	protected static void createBodyColor(HSSFWorkbook workbook, HSSFSheet sheet, 
			List list, Map color, int currentRow) {

        HSSFFont font_black = getFont(workbook, 10, HSSFFont.BOLDWEIGHT_NORMAL, HSSFColor.BLACK.index);
        HSSFCellStyle style_black = getStyle(workbook, font_black, HSSFCellStyle.ALIGN_CENTER);
        HSSFFont font_red = getFont(workbook, 10, HSSFFont.BOLDWEIGHT_NORMAL, HSSFColor.RED.index);
        HSSFCellStyle style_red = getStyle(workbook, font_red, HSSFCellStyle.ALIGN_CENTER);
        HSSFFont font_green = getFont(workbook, 10, HSSFFont.BOLDWEIGHT_NORMAL, HSSFColor.GREEN.index);
        HSSFCellStyle style_green = getStyle(workbook, font_green, HSSFCellStyle.ALIGN_CENTER);

        for (int index = 0; index < list.size(); index++) {
            String rowColor = (String) color.get(index);


            HSSFRow row = sheet.createRow(currentRow);
            String[] stringArray = (String[]) list.get(index);
            for (int j = 0; j < stringArray.length; j++) {
                if (rowColor != null) {
                    if (rowColor.equals("RED")) {
                        createCell(row, j, style_red, stringArray[j]);
                    } else if (rowColor.equals("GREEN")) {
                        createCell(row, j, style_green, stringArray[j]);
                    } else {
                        createCell(row, j, style_black, stringArray[j]);
                    }
                } else {
                    createCell(row, j, style_black, stringArray[j]);
                }

            }
            currentRow++;
        }
    }

    /**
     * 创建合并一列的主体数据
     *
     * @param map        Map(List(String[])) 嵌套一层的Map数据
     * @param sheet
     * @param currentRow
     */
    @SuppressWarnings("rawtypes")
	protected static void createOneMapBody(HSSFWorkbook workbook, HSSFSheet sheet, Map map, int currentRow) {

        HSSFFont font = getFont(workbook, 10, HSSFFont.BOLDWEIGHT_NORMAL, HSSFColor.BLACK.index);
        HSSFCellStyle style = getStyle(workbook, font, HSSFCellStyle.ALIGN_CENTER);

        for (Iterator it = map.keySet().iterator(); it.hasNext(); ) {
            String key = (String) it.next();
            List list = (List) map.get(key);
            int size = list.size();
            mergeRow(sheet, currentRow, currentRow + size - 1, 0);

            for (int i = 0; i < size; i++) {
                HSSFRow row = sheet.createRow(currentRow);
                createCell(row, 0, style, key);

                String[] stringArray = (String[]) list.get(i);
                for (int j = 0; j < stringArray.length; j++) {
                    createCell(row, j + 1, style, stringArray[j]);
                }
                currentRow++;
            }
        }
    }

    /**
     * 创建合并二列的主体数据
     *
     * @param map        Map(Map(List(String[]))) 嵌套二层的Map数据
     * @param sheet
     * @param currentRow
     */
    @SuppressWarnings("rawtypes")
	protected static void createTwoMapBody(HSSFWorkbook workbook, HSSFSheet sheet, Map map, int currentRow) {

        HSSFFont font = getFont(workbook, 10, HSSFFont.BOLDWEIGHT_NORMAL, HSSFColor.BLACK.index);
        HSSFCellStyle style = getStyle(workbook, font, HSSFCellStyle.ALIGN_CENTER);

        //第一列的合并行数
        int[] rowSpans = getRowSpanOfTwoMap(map);
        int rowCount = 0;
        for (Iterator iterator = map.keySet().iterator(); iterator.hasNext(); rowCount++) {

            String key1 = (String) iterator.next();
            Map map1 = (Map) map.get(key1);

            mergeRow(sheet, currentRow, currentRow + rowSpans[rowCount] - 1, 0);

            for (Iterator it2 = map1.keySet().iterator(); it2.hasNext(); ) {
                String key2 = (String) it2.next();
                List list = (List) map1.get(key2);
                int size = list.size();
                mergeRow(sheet, currentRow, currentRow + size - 1, 1);

                for (int i = 0; i < size; i++) {
                    HSSFRow row = sheet.createRow(currentRow);
                    createCell(row, 0, style, key1);
                    createCell(row, 1, style, key2);

                    String[] stringArray = (String[]) list.get(i);
                    for (int j = 0; j < stringArray.length; j++) {
                        createCell(row, j + 2, style, stringArray[j]);
                    }
                    currentRow++;
                }
            }
        }
    }

    /**
     * 创建单元格
     *
     * @param row   行对象
     * @param index 在行中创建单元格的位置,从0开始。
     * @param style 单元格样式
     * @param value 单元格的值
     */
	protected static void createCell(HSSFRow row, int index, HSSFCellStyle style, String value) {

        HSSFCell cell = row.createCell((short) index);
        //cell.setEncoding(HSSFCell.ENCODING_UTF_16);
        cell.setCellStyle(style);
        cell.setCellValue(value);
    }

    /**
     * 合并行
     *
     * @param sheet
     * @param startRow 起始行(从0开始)
     * @param endRow   结束行(从0开始)
     * @param col      列位置(从0开始)
     */
	protected static void mergeRow(HSSFSheet sheet, int startRow, int endRow, int col) {

        sheet.addMergedRegion(new Region(startRow, (short) col, endRow, (short) col));
    }

    /**
     * 合并列
     *
     * @param sheet
     * @param startCol 起始列(从0开始)
     * @param endCol   结束列(从0开始)
     * @param row      行位置(从0开始)
     */
	protected static void mergeCol(HSSFSheet sheet, int startCol, int endCol, int row) {

        sheet.addMergedRegion(new Region(row, (short) startCol, row, (short) endCol));
    }

    /**
     * 合并区域
     *
     * @param sheet
     * @param startRow 起始行(从0开始)
     * @param startCol 起始列(从0开始)
     * @param endRow   结束行(从0开始)
     * @param endCol   结束列(从0开始)
     */
	protected static void mergeRegion(HSSFSheet sheet, int startRow, int startCol, int endRow, int endCol) {

        sheet.addMergedRegion(new Region(startRow, (short) startCol, endRow, (short) endCol));
    }

    /**
     * 关闭输出流
     *
     * @param out 输出流
     */
    protected static void closeOutputStream(OutputStream out) {

        if (out != null) {
            try {
                out.close();
            } catch (IOException e) {

            }
        }
    }

    /**
     * 根据字体高度和字体类型获得字体对象
     *
     * @param fontHeight 字体高度
     * @param boldweight 字体类型
     * @param color      字体颜色
     * @return 字体对象
     */
    protected static HSSFFont getFont(HSSFWorkbook workbook, int fontHeight, short boldweight, short color) {

        HSSFFont font = workbook.createFont();
        font.setFontHeightInPoints((short) fontHeight);
        font.setFontName("新宋体");
        font.setColor(color);
        font.setBoldweight(boldweight);
        return font;
    }

    /**
     * 根据字体和对其方式获得单元格样式
     *
     * @param font  字体
     * @param align 对其方式
     * @return 单元格样式
     */
    protected static HSSFCellStyle getStyle(HSSFWorkbook workbook, HSSFFont font, short align) {

        HSSFCellStyle style = workbook.createCellStyle();
        style.setFont(font);
        //边框
        style.setBorderBottom(HSSFCellStyle.BORDER_THIN);
        style.setBottomBorderColor(HSSFColor.BLACK.index);
        style.setBorderLeft(HSSFCellStyle.BORDER_THIN);
        style.setLeftBorderColor(HSSFColor.BLACK.index);
        style.setBorderRight(HSSFCellStyle.BORDER_THIN);
        style.setRightBorderColor(HSSFColor.BLACK.index);
        style.setBorderTop(HSSFCellStyle.BORDER_THIN);
        style.setTopBorderColor(HSSFColor.BLACK.index);
        //对齐方式
        style.setAlignment(align);
        style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
        return style;
    }

    /**
     * 获得报表标题在某行某列的行跨度
     *
     * @param colTitles 报表列标题
     * @param row       行
     * @param col       列
     * @return 行跨度
     */
    protected static int getRowSpan(String[][] colTitles, int row, int col) {

        int rowSpan = 1;
        if (colTitles[row][col] != null) {
            for (int i = row + 1; i < colTitles.length; i++) {
                if (colTitles[i][col] == null) {
                    rowSpan++;
                } else {
                    break;
                }
            }
        }
        return rowSpan;
    }

    /**
     * 获得报表标题在某行某列的列跨度
     *
     * @param colTitles 报表列标题
     * @param row       行
     * @param col       列
     * @return 列跨度
     */
    protected static int getColSpan(String[][] colTitles, int row, int col) {

        int colSpan = 1;
        if (colTitles[row][col] != null) {
            for (int i = col + 1; i < colTitles[row].length; i++) {
                if (colTitles[row][i] == null) {
                    if (row == 0) {
                        colSpan++;
                    } else if (colTitles[row - 1][i] == null) {
                        colSpan++;
                    } else {
                        break;
                    }
                } else {
                    break;
                }
            }
        }
        return colSpan;
    }

    /**
     * 获得Map或List数据的嵌套层次数。
     *
     * @param obj Map 或 List
     * @return 如果参数为null则返回-1;
     *         如果参数为List则返回0;
     *         如果为一层Map(Map中value为List)则返回1;
     *         如果为二层Map(Map中value为Map,再深层为List,则返回2;
     *         ......
     */
    @SuppressWarnings("rawtypes")
	protected static int getNestedCount(Object obj) {

        if (obj == null) {
            return -1;
        } else if (obj instanceof List) {
            return 0;
        } else if (obj instanceof Map) {
            Map map = (Map) obj;
            if (map.size() > 0) {
                Object o = map.get(map.keySet().iterator().next());
                return getNestedCount(o) + 1;
            } else {
                return 1;
            }
        }
        throw new IllegalArgumentException("参数不为List或Map");
    }

    /**
     * 获得两层嵌套Map的针对报表的第一列合并行情况
     *
     * @param map Map(Map(List))两层嵌套Map
     * @return 对应报表的第一列合并行情况
     */
    @SuppressWarnings({ "rawtypes", "unused" })
	protected static int[] getRowSpanOfTwoMap(Map map) {

        int[] spans = new int[map.size()];
        Iterator it = map.keySet().iterator();
        for (int i = 0; it.hasNext(); i++) {
            Object key = it.next();
            Map map2 = (Map) map.get(key);
            Iterator it2 = map2.keySet().iterator();
            for (int i2 = 0; it2.hasNext(); i2++) {
                Object key2 = it2.next();
                List list = (List) map2.get(key2);
                spans[i] += list.size();
            }
        }
        return spans;
    }
}

 

  • 大小: 179.7 KB
分享到:
评论

相关推荐

    Anroid开发所需poi_jar包

    开发中经常会设计到excel的处理,如导出Excel,导入Excel到数据库中,操作Excel目前有两个框架,一个是apache 的poi, 另一个是 Java Excel Apache POI 简介是用Java编写的免费开源的跨平台的 Java API,Apache POI...

    Apache POI教程

    Apache POI是一种流行的API,它允许程序员使用Java程序创建,修改和显示MS Office文件。这由Apache软件基金会开发使用Java分布式设计或修改Microsoft Office文件的开源库。它包含类和方法对用户输入数据或文件到MS ...

    autopoi:AutoPOI 功能仅仅5行代码就可以完成Excel的导入导出

    AutoPOI (Excel和 Word简易工具类)AutoPOI 功能如同名字auto,追求的就是自动化,让一个没接触过poi的人员,可以傻瓜化的快速实现Excel导入导出、Word模板导出、可以仅仅5行代码就可以完成Excel的导入导出。...

    java 操作Excel表格用到的jar 包

    Apache POI是一种流行的API,它允许程序员使用Java程序创建,修改和显示MS Office文件。这由Apache软件基金会开发使用Java分布式设计或修改Microsoft Office文件的开源库。它包含类和方法对用户输入数据或文件到MS ...

    基于SSH2图书管理系统升级版(源码+运行截图+演示视频).zip

    采用技术: SSH2(Struts2 + Spring + Hibernate),标准SSH2框架,采用了基于注解方式管理bean和事务,使用poi进行excel批量导出 图书类型:图书类别,类别名称,可借阅天数 图书:图书条形码,图书名称,图书所在...

    JAVA办公自动化系统的设计

    表格编辑模块:该模块可以创建、编辑各种类型的表格,例如Excel表格、Access数据库表等,同时还可以进行表格的数据查询、排序、过滤等操作。 邮件发送模块:该模块可以帮助用户发送邮件,包括设置邮件主题、收件人...

    Java毕业设计-JAVA办公自动化系统(源代码+论文+外文翻译).rar

    3. **Apache POI**:一个用于操作Microsoft Office文档的Java库,支持创建、读取和修改Excel、Word、PowerPoint等文件。 4. **Quartz**:一个功能丰富的任务调度库,支持定时任务、集群和持久化。 5. **Redis**:一...

    CRM-System::chart_increasing:客户关系管理(CRM)系统。 它可以管理供应商,员工,客户和产品。 通过电子邮件确认帐户。 您可以将报告创建为PDF和Excel

    经理可以创建有关产品,客户,供应商等的报告。此类报告可以导出为PDF或Excel文件。 该系统的设计方式是只有管理员才能为新用户注册帐户。 管理员用新雇员的数据填写注册表,然后该雇员收到一封电子邮件,其中他...

    templateIt-开源

    基于模板的Excel / PDF文件生成器(Java / Apache POI / iText)。 不需要报表设计器。 模板是在Excel工作簿中创建的。 允许生成复杂的Excel文档。 简单易用,易于学习。

    大数据应用测试经验总结.pdf

    使⽤Apache POI实现excel、CSV的导⼊导出;使⽤Log4J记录⽇志;使⽤Spring框架实现 页⾯、服务、数据的集成管理;使⽤DBCP实现数据库连接池。 7. 数据模型层次说明 ODS:贴源层,存储原始数据,数据采集直接写⼊; ...

    Java范例开发大全 (源程序)

     实例139 利用POI读取Word文件中的内容 208  7.3 字符流 209  实例140 按顺序创建文件 210  实例141 按顺序读取文件 211  实例142 追加文件内容 211  实例143 只显示文件中指定的字符 214  实例144 ...

    java范例开发大全(pdf&源码)

    实例139 利用POI读取Word文件中的内容 208 7.3 字符流 209 实例140 按顺序创建文件 210 实例141 按顺序读取文件 211 实例142 追加文件内容 211 实例143 只显示文件中指定的字符 214 实例144 读取jar包文件 215 实例...

    java范例开发大全源代码

     实例139 利用POI读取Word文件中的内容 208  7.3 字符流 209  实例140 按顺序创建文件 210  实例141 按顺序读取文件 211  实例142 追加文件内容 211  实例143 只显示文件中指定的字符 214  实例...

    java范例开发大全

    实例139 利用POI读取Word文件中的内容 208 7.3 字符流 209 实例140 按顺序创建文件 210 实例141 按顺序读取文件 211 实例142 追加文件内容 211 实例143 只显示文件中指定的字符 214 实例144 读取jar包文件 215 实例...

    Java范例开发大全(全书源程序)

    实例139 利用POI读取Word文件中的内容 208 7.3 字符流 209 实例140 按顺序创建文件 210 实例141 按顺序读取文件 211 实例142 追加文件内容 211 实例143 只显示文件中指定的字符 214 实例144 读取jar包文件 ...

Global site tag (gtag.js) - Google Analytics