`
lizhenbin2010
  • 浏览: 101270 次
  • 性别: 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
分享到:
评论

相关推荐

    使用POI向Excel模板动态添加内容

    在“使用POI向Excel模板动态添加内容”时,我们通常会有一个预先设计好的Excel模板,这个模板包含了固定格式和一些占位符。我们的任务就是通过编程方式找到这些占位符,并用实际数据替换它们。这一过程可以极大地...

    POI导出Excel表格

    - 使用POI创建`Workbook`对象,然后添加`Sheet`,接着为每个实体对象创建一行数据(`Row`)并填充单元格(`Cell`)。 - 如果使用反射,可以遍历实体类的所有字段,动态生成Excel列头并设置数据。 - 将工作簿写入...

    POI操作Excel的封装

    在封装POI操作Excel的过程中,反射可能被用来动态地创建对象,调用方法,或访问私有成员,这使得代码更具灵活性和可扩展性。例如,可以使用反射动态地根据Excel工作表的列名创建对应的Java对象属性,或者在不知道...

    POI-excel导出样式设计.docx

    POI-excel 导出样式设计 POI(Apache POI)是一款 Java 库,用于读取和写入 Microsoft Office 文件格式,包括 Excel、Word 和 PowerPoint。POI-excel 是 POI 中处理 Excel 文件的部分,本文将介绍 POI-excel 的一些...

    基于POI的Excel多Sheet页导出导入工具类

    "基于POI的Excel多Sheet页导出导入工具类"是一个实用的Java类库,专为处理Excel文件中的多个工作表(Sheet)而设计,提供了一种高效且灵活的方式来操作Excel数据。 该工具类的核心功能包括: 1. **多Sheet页操作**...

    poi导出excel所需jar

    - 图表和图像:如果需要,可以使用POI创建图表或者嵌入图片。 - 多线程:对于大规模数据,可以考虑使用多线程并行处理。 总之,Apache POI提供了一套强大的工具集,让Java开发者能够方便地与Excel文件交互。了解和...

    poi 解析excel实例

    Apache POI 是一个开源项目,专门用于处理Microsoft Office格式的文件,包括Excel、Word和PowerPoint等。在Java环境中,Apache POI 提供了API来读取、创建和修改这些文件。在这个“poi 解析excel实例”中,我们主要...

    POI兼容Excel2003和2007

    使用POI创建Excel文件时,首先需要创建`Workbook`对象。对于Excel 2003,使用`HSSFWorkbook`;对于Excel 2007,使用`XSSFWorkbook`。接着,可以创建`Sheet`对象表示工作表,再创建`Row`对象表示行,最后创建`Cell`...

    使用poi从数据库导出excel表的示例

    3. **使用Apache POI创建Excel工作簿**:在Java代码中,导入必要的POI库,然后创建一个HSSFWorkbook对象(对于老版本的XLS格式)或XSSFWorkbook对象(对于新版本的XLSX格式)。这将是我们的Excel文件的容器。 4. **...

    POI技术将excel解析导入mysql.pdf

    根据提供的文件信息,可以看出文档主要阐述了如何使用Apache POI技术解析2003-2007版本的Excel文档,并将解析后的数据导入到MySQL数据库中。文档中分别涉及到Java实体类的设计(User.java),以及数据访问层的设计...

    java导出excel POI jar包

    最后,`poi-excelant-3.15-beta1.jar`是为了支持Apache Ant构建工具而设计的,它允许你在Ant脚本中直接使用POI进行Excel文件的处理。 使用POI导出Excel的基本步骤如下: 1. 创建`Workbook`对象,这代表一个Excel...

    java使用poi在excel单元格添加超链接,设置字体颜色(csdn)————程序.pdf

    在Java开发中,Apache POI库是一个非常实用的工具,用于读取、写入和修改Microsoft Office格式的文件,特别是Excel。本篇文章主要探讨如何利用POI在Excel单元格中添加超链接,并设置字体颜色。 首先,为了使用...

    poi操作excel

    - 使用POI创建一个新的Excel文件,将List数据写入工作表中。 - 设置响应头,返回生成的Excel文件供用户下载。 在实际开发中,可能还需要考虑错误处理、文件上传大小限制、并发性能等问题。以上就是关于"poi操作...

    poi 基于excel模板导出功能

    二、创建Excel模板 1. 模板设计:在Excel中创建模板,设置好需要动态填充的数据区域,如单元格样式、公式、条件格式等。 2. 保存模板:将模板文件保存为.xlsx格式,以便于POI读取。 三、使用POI读取模板并填充数据 ...

    jxls-poi导出excel示例代码文件

    这样,我们就可以避免繁琐的Excel编程,只需关注数据和模板的设计。 在描述中提到的"读取json转为excel文件导出",这正是`jxls`的一个典型应用场景。我们通常会有一个JSON数据源,它包含我们需要导出到Excel的数据...

    JXL 和 POI 操作Excel 表格

    例如,使用Apache POI创建一个Excel文件: ```java import org.apache.poi.ss.usermodel.*; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import java.io.FileOutputStream; import java.io.IOException; ...

    Spring3 MVC + POI 实现 Excel与MySQL 的导入导出

    这需要先执行SQL查询,获取需要的数据集,然后使用POI创建一个新的Excel工作簿和工作表,将数据逐条写入工作表的单元格。完成后,可以将工作簿写入到响应流,供用户下载。 在实际应用中,我们还需要考虑一些其他...

    poi3.9读写EXCEL

    2. HSSF与XSSF:在POI中,HSSF用于处理老版本的二进制XLS文件,而XSSF则专为XML结构的XLSX文件设计。这两种模型提供了类似的接口,使得代码在不同格式之间切换变得更加容易。 二、读取Excel文件 1. 创建Workbook...

    POI处理Excel文件.zip

    这使得我们可以通过解析XML来操作Excel内容,而POI库正是为此设计的。SAX(Simple API for XML)是一种基于事件驱动的XML解析方法,它在内存中不加载整个XML文档,而是逐个处理XML事件,如开始元素、结束元素、文本...

    android中poi生成word文档和excel文档

    在Android开发中,Apache POI 是一个非常实用的库,它允许程序员创建、修改和显示Microsoft Office格式的文件,如Word文档(.doc)和Excel工作簿(.xlsx或.xls)。这个工具对于需要在Android应用中处理这些文档的...

Global site tag (gtag.js) - Google Analytics