导出Excel工具类(一个主表多个明细表)

①ExcelData.java(Excel数据封装类)

package com.kentra.util;

import java.util.List;
import java.util.Map;
/**
 * 
 * 描述:为导出Excel文件封装数据
 * 封装Excel文件数据注意事项:
 * 1.heads(标题行):是一个字符串, 标题与标题之间以逗号分隔如:hears="学号,姓名,性别"
 * 2.data: 表示:主数据集合,data是个字符串集合,包含了所有主数据,集合中的一个字符串元素就是Excel表格中的一行记录;
 * 列数据项与列数项之间用冒号分隔, 如果某个列数据项值为空, 就用null代替,如: data.add("001:老李:null:15056786789:null");
 * 3.assoceData 关联数据集合,主数据集合的字符串元素的下标在关联数据集合就是对应的关联数据.是个双list集合字符串,包含了所有主数据的关联数据集合,
 * 它的每一个元素就是某一行主数据的关联数据集合,如果主表数据没有关联数据,那么它的关联数据,就用null代替
 * 4.widthAndHeiht map的key 表示列的位置,map的value 表示列的宽度, 如:widthAndHeiht.put(3, 5000); 第4列宽度为5000英寸
 * 5.length 合并单元格的个数
 * @author sunxuefeng 2017年7月28日 下午5:13:35
 * @version 1.0
 */

public class ExcelData {

    private String                excelName;    // Excel文件名称
    private String                sheetName;    // 工作表的名称
    private String                heads;        // 标题行
    private List<String>          data;         // 主数据
    private Map<Integer, Integer> widthAndHeiht;// 单元格的宽高,如:xSheet.setColumnWidth(10,1000);
                                                // 10表示:map的key, //
                                                // 10,1000表示:map的value
    private List<List<String>>    assoceData;   // 关联数据行,一张主表对应一个从表,当有多个明细表的时候,那么就全部拼接到这个从表中即可。
    private int                   length;       // 合并单元格的个数 没有就不用填

    public String getHeads() {
        return heads;
    }

    public void setHeads(String heads) {
        this.heads = heads;
    }

    public int getLength() {
        return length;
    }

    public void setLength(int length) {
        this.length = length;
    }

    public List<List<String>> getAssoceData() {
        return assoceData;
    }

    public void setAssoceData(List<List<String>> assoceData) {
        this.assoceData = assoceData;
    }

    public String getExcelName() {
        return excelName;
    }

    public void setExcelName(String excelName) {
        this.excelName = excelName;
    }

    public String getSheetName() {
        return sheetName;
    }

    public void setSheetName(String sheetName) {
        this.sheetName = sheetName;
    }

    public List<String> getData() {
        return data;
    }

    public void setData(List<String> data) {
        this.data = data;
    }

    public Map<Integer, Integer> getWidthAndHeiht() {
        return widthAndHeiht;
    }

    public void setWidthAndHeiht(Map<Integer, Integer> widthAndHeiht) {
        this.widthAndHeiht = widthAndHeiht;
    }

}

②ExportExcelUtils.java(导出工具类)

package com.kentra.util;

import java.net.URLEncoder;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFFont;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

/**
 * 
 * 描述:导出excel文件模板
 * 
 * @author sunxuefeng 2017年7月28日 上午11:20:48
 * @version 1.0
 */
public class ExportExcelUtils {
    private static final Logger LOG = Logger.getLogger(ExportExcelUtils.class);

    /**
     * 
     * 描述:输出Excel文件
     * 
     * @param response
     * @param excelData
     *            为导出Excel文件封装数据
     * @author sunxuefeng 2017年7月31日 上午9:58:10
     * @version 1.0
     * @throws Exception
     */
    public static void exportFile(HttpServletResponse response, ExcelData excelData) {
        ServletOutputStream outputStream = null;
        try {
            outputStream = response.getOutputStream();
            response.setHeader("Content-disposition",
                    "attachment; filename = " + URLEncoder.encode(excelData.getExcelName() + ".xlsx", "UTF-8"));
            response.setContentType("application/octet-streem");
            List<List<String>> assoceData = excelData.getAssoceData();
            XSSFWorkbook workbook = null;
            if (assoceData != null && assoceData.size() > 0) {
                workbook = setSheetContent(excelData);
            } else {
                workbook = setSheetContentNO(excelData);
            }
            workbook.write(outputStream);
        } catch (Exception e) {
            LOG.error("Excel文件导出失败:" + e.getMessage());
        } finally {
            if (outputStream != null) {
                try {
                    outputStream.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 
     * 描述: set Sheet标题行
     * 
     * @param xWorkbook
     * @param xSheet
     * @param headers标题行
     * @author sunxuefeng 2017年7月28日 下午1:13:36
     * @version 1.0
     */
    private static void setSheetHeader(XSSFWorkbook xWorkbook, XSSFSheet xSheet, String headers) {
        // 设置样式
        CellStyle cs = xWorkbook.createCellStyle();
        // 设置水平垂直居中
        cs.setAlignment(CellStyle.ALIGN_CENTER);
        cs.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
        // 设置字体
        Font headerFont = xWorkbook.createFont();
        headerFont.setFontHeightInPoints((short) 12);
        headerFont.setBoldweight(XSSFFont.BOLDWEIGHT_BOLD);
        headerFont.setFontName("宋体");
        cs.setFont(headerFont);
        cs.setWrapText(false);// 是否自动换行
        XSSFRow xRow0 = xSheet.createRow(0);
        String[] header = headers.split(",");
        for (int i = 0, length = header.length; i < length; i++) {
            XSSFCell xCell = xRow0.createCell(i);
            xCell.setCellStyle(cs);
            xCell.setCellValue(header[i]);
        }
    }

    /***
     * 
     * 描述: 设置Sheet页内容(有关联数据)
     * 
     * @param excelData
     * @return
     * @author sunxuefeng 2017年7月31日 上午9:59:24
     * @version 1.0
     */
    private static XSSFWorkbook setSheetContent(ExcelData excelData) {
        XSSFWorkbook xWorkbook = new XSSFWorkbook();
        XSSFSheet xSheet = xWorkbook.createSheet(excelData.getSheetName());
        Map<Integer, Integer> map = excelData.getWidthAndHeiht();
        CellStyle cs = xWorkbook.createCellStyle(); // 设置样式
        cs.setAlignment(CellStyle.ALIGN_CENTER);
        cs.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
        cs.setWrapText(true); // 是否自动换行。加入\n 就会换行, eg:电子科技大学2 \n 北京大学
        setSheetHeader(xWorkbook, xSheet, excelData.getHeads());
        if (map != null && map.size() > 0) { // 设置单元格的宽高
            for (Integer key : map.keySet()) {
                xSheet.setColumnWidth(key, map.get(key));
            }
        }
        List<String> data = excelData.getData();
        List<List<String>> assoceDatas = excelData.getAssoceData();
        if (data != null && data.size() > 0) {
            int l = 0, ii = 0;
            for (int i = 0; i < data.size(); i++) {
                List<String> assoceData = assoceDatas.get(i);
                int assoceDataSize = 0;
                boolean assoceDataFlag = false;
                if (assoceData != null && assoceData.size() > 0) {
                    assoceDataSize = assoceData.size();
                    assoceDataFlag = true;
                    if (i == 0) {
                        ii = 0;
                        l = assoceDataSize;
                    } else {
                        ii = l;
                        l += assoceDataSize;
                    }
                } else {
                    if (i == 0) {
                        ii = 0;
                        l = 1;
                    } else {
                        ii = l;
                        l += 1;
                    }
                }
                for (int k = ii, m = 0, lengths = l; k < lengths; k++, m++) {// 控制行行:
                    XSSFRow xRow = xSheet.createRow(k + 1);
                    int j = 0;
                    j = setValue(j, 0, data.get(i), xRow, cs);// 设置主数据
                    int length = data.get(i).split(":").length;
                    if (assoceDataFlag) {
                        setValue(j, length, assoceData.get(m), xRow, cs);// 设置关联数据
                    }
                }
                if (assoceDatas.size() >= 1) { // 合并单元格
                    for (int m = 0; m < excelData.getLength(); m++) {
                        if (assoceDataFlag) {
                            int endRows = xSheet.getLastRowNum();
                            int startRow = endRows - assoceDataSize + 1;
                            xSheet.addMergedRegion(new CellRangeAddress(startRow, endRows, m, m));
                        }
                    }
                }
            }
        }
        return xWorkbook;
    }

    /***
     * 
     * 描述: 设置Sheet页内容(无关联数据)
     * 
     * @param excelData
     * @return
     * @author sunxuefeng 2017年7月31日 上午9:59:24
     * @version 1.0
     */
    private static XSSFWorkbook setSheetContentNO(ExcelData excelData) throws Exception {
        XSSFWorkbook xWorkbook = new XSSFWorkbook();
        XSSFSheet xSheet = xWorkbook.createSheet(excelData.getSheetName());
        Map<Integer, Integer> map = excelData.getWidthAndHeiht();
        CellStyle cs = xWorkbook.createCellStyle(); // 设置样式
        cs.setAlignment(CellStyle.ALIGN_CENTER);
        cs.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
//        cs.setWrapText(false); // 是否自动换行
        cs.setWrapText(true); // 是否自动换行
        setSheetHeader(xWorkbook, xSheet, excelData.getHeads());
        if (map != null && map.size() > 0) { // 设置单元格的宽
            for (Integer key : map.keySet()) {
                xSheet.setColumnWidth(key, map.get(key));
            }
        }
        List<String> data = excelData.getData();
        if (data != null && data.size() > 0) {
            for (int i = 0; i < data.size(); i++) {
                XSSFRow xRow = xSheet.createRow(i + 1);
                int j = 0;
                j = setValue(j, 0, data.get(i), xRow, cs);// 设置主数据
            }
        }
        return xWorkbook;
    }

    /**
     * 
     * 描述:为单元格设置值
     * 
     * @author sunxuefeng 2017年8月1日 上午9:45:36
     * @version 1.0
     */
    private static int setValue(int j, int i, String data, XSSFRow xRow, CellStyle cs) {
        String[] strings = data.split(":");
        for (; j < strings.length + i; j++) {
            String dString = strings[j - i];
            if (dString != null && !dString.equals("") && !dString.equals("null")) {
                XSSFCell xCell = xRow.createCell(j);
                xCell.setCellStyle(cs);
                xCell.setCellValue(dString);
            }
        }
        return j;
    }
}

③导出示例(当有多个明细表时,都拼接到从表后面)

/**
	 *测试导出员工
	 * 
	 */
	@RequestMapping(value="/ExportExcel")
	public void ExportExcel(HttpServletResponse response)throws Exception{
		ExcelData excelData = new ExcelData();
		excelData.setExcelName("员工信息表");
		excelData.setSheetName("员工信息表");
		excelData.setHeads("序号,姓名,性别,年龄,学校,毕业年份,学分,家庭成员,年龄");
		//列宽
		Map<Integer, Integer> widthAndHeiht = new HashMap<>();
		widthAndHeiht.put(0, 2000);
		widthAndHeiht.put(1, 3000);
		widthAndHeiht.put(2, 3000);
		widthAndHeiht.put(4, 8000);
		excelData.setWidthAndHeiht(widthAndHeiht);
		//主表
		String data1 = "1,李建波,null,26";
		String data2 = "2,李雨锋,男,20";
		String data3 = "3,魏文莹,null,null";
		List<String> data = new ArrayList<>();
		data.add(data1);
		data.add(data2);
		data.add(data3);
		excelData.setData(data);
		//合并单元格
		excelData.setLength(2);
		//关联明细表
		List<List<String>>    assoceData = new ArrayList<>();
		//教育明细
		String jioayu1 = "四川大学,2017,5,父亲,60";
		String jioayu2 = "电子科技大学,2015,4,母亲,55";
		String jioayu33 = "null,null,null,妻子,25";
		List<String> jiaoyulist1 = new ArrayList<>();
		jiaoyulist1.add(jioayu1);
		jiaoyulist1.add(jioayu2);
		jiaoyulist1.add(jioayu33);
		String jioayu3 = "四川大学2,2017,null";
		String jioayu4 = "电子科技大学2 \n 北京大学,2015,4";
		List<String> jiaoyulist2 = new ArrayList<>();
		jiaoyulist2.add(jioayu3);
		jiaoyulist2.add(jioayu4);
		//
		assoceData.add(jiaoyulist1);
		assoceData.add(null);
		assoceData.add(jiaoyulist2);
		excelData.setAssoceData(assoceData);
		//导出
		ExportExcelUtils.exportFile(response, excelData);

	}

注意事项:

导出Excel的时候,我们可能需要某一个单元格中的内容自动换行,那么我们可以在需要换行的地方拼接一个 “\n” 那么导出数据就会换行。

该工具类主要是为了导出员工信息表。一个主表多个明细表。比如一个员工有多条工作经历,有多个家庭成员,有多个证件等。

(二)、如何手动实现页面可选择特定字段导出。

我们的思路是页面勾选哪几个字段,我们就拼接哪几个字段然后导出。表头名字来自于选择的复选框的text();内容则通过每个字段对应的value值作为下标去从一条记录(数组)中去获取对应下标的值,然后进行拼接字符串。

<div style="padding-top:10px">
		<div>
		<!-- 修改,将span加在了后面-->
		<input type="checkbox" value="1" name="staffinfo_checkbox"/><span>部门</span>
		<input type="checkbox" value="2" name="staffinfo_checkbox"/><span>姓名</span>
		<input type="checkbox" value="3" name="staffinfo_checkbox"/><span>性别</span>
		<input type="checkbox" value="4" name="staffinfo_checkbox"/><span>手机号</span>
		<input type="checkbox" value="5" name="staffinfo_checkbox"/><span>民族</span>
		<input type="checkbox" value="6" name="staffinfo_checkbox"/><span>籍贯</span>
		<input type="checkbox" value="7" name="staffinfo_checkbox"/><span>出生地</span>
		<input type="checkbox" value="8" name="staffinfo_checkbox"/><span>出生日期</span>
		<input type="checkbox" value="9" name="staffinfo_checkbox"/><span>年龄</span>
</div>
时间: 2024-10-07 05:45:35

导出Excel工具类(一个主表多个明细表)的相关文章

javaEE开发之导出excel工具类

web开发中,一个系统的普通需求也包含导出excel,一般採用POI做统计报表导出excel. 导出excel工具类: import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.util.List; import java.util.Map; import org.apache.poi.hssf.usermodel.HSSFCell; import o

Java 通过Xml导出Excel文件,Java Excel 导出工具类,Java导出Excel工具类

Java 通过Xml导出Excel文件,Java Excel 导出工具类,Java导出Excel工具类 ============================== ?Copyright 蕃薯耀 2017年9月13日 http://www.cnblogs.com/fanshuyao/ 直接上代码: import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.lang.ref

web开发之导出excel工具类

web开发中,一个系统的普通需求也包括导出excel,一般采用POI做统计报表导出excel. 导出excel工具类: import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.util.List; import java.util.Map; import org.apache.poi.hssf.usermodel.HSSFCell; import o

导出Excel工具类

导出Excel的工具方法,主要是生成excel文件: public static void writeFailureReasonToExcelFile(List<FailureReasonResponseEntity> queryAllFailureReasonCountList,String path){ try { //创建一个工作簿 excel文件 XSSFWorkbook workbook = new XSSFWorkbook(); //创建一个标签页 XSSFSheet sheet

JXL导出Excel工具类

将Excel中的数据读取到List<Map<String, Object>>集合中 package com.mvc.util; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.Field;

配置简单功能强大的excel工具类搞定excel导入导出工具类(一)

对于J2EE项目导入导出Excel是最普通和实用功能,本工具类使用步骤简单,功能强大,只需要对实体类进行简单的注解就能实现导入导出功能,导入导出操作的都是实体对象. 请看一下这个类都有哪些功能:????? 1.实体属性配置了注解就能导出到excel中,每个属性都对应一列.????? 2.列名称可以通过注解配置.????? 3.导出到哪一列可以通过注解配置.????? 4.鼠标移动到该列时提示信息可以通过注解配置.????? 5.用注解设置只能下拉选择不能随意填写功能.???? ? 6.用注解设置

java poi导出excel 工具

基本上每个系统或多或少都有一些导出功能,我之前做的系统是针对每个功能定制一个导出,而且我看网上的也大多是这么做的,这样就存在一个代码冗余的问题,而且增加工作量,今天整理了一下,系统中所有的导出都可以引用(注意我这里说的是excel,word的暂时还没整理),并且支持导出图片,上代码. 1. jar包准备 如果你是新手请参考 https://blog.csdn.net/fulishafulisha/article/details/80152805 ,如果使用的maven <dependency>

MVC NPOI Linq导出Excel通用类

之前写了一个模型导出Excel通用类,但是在实际应用中,可能不是直接导出模型,而是通过Linq查询后获取到最终结果再导出 通用类: public enum DataTypeEnum { Int = 0, Float = 1, Double = 2, String = 3, DateTime = 4, Date = 5 } public class ExportFieldInfo { /// <summary> /// 字段名,用于反射获取值 /// </summary> publi

导出Excel帮助类

using System; using System.Collections.Generic; using System.Text; using System.Data; using System.Data.OleDb; using System.Web; using System.Web.UI; namespace AIMSCommon { /// <summary> /// 导出Excel帮助类 /// </summary> public class ExcelHelper {