java动态导出Excle模板

java

实际开发中很多时候都需要导出Excle模板文件,而且是根据不同的需求需要导出不同的模板,在这里简单记录一下使用java实现普通的动态Excle模板导出功能。

1.添加maven依赖:

		<dependency>

<groupId>org.apache.poi</groupId>

<artifactId>poi</artifactId>

<version>3.8</version>

</dependency>

<dependency>

<groupId>org.apache.poi</groupId>

<artifactId>poi-ooxml</artifactId>

<version>3.8</version>

</dependency>

<dependency>

<groupId>org.apache.poi</groupId>

<artifactId>poi-ooxml-schemas</artifactId>

<version>3.8</version>

</dependency>

  1. 编写导出工具类:

import java.io.OutputStream;

import java.util.ArrayList;

import java.util.Arrays;

import java.util.HashMap;

import java.util.List;

import java.util.Map;

import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;

import org.apache.poi.hssf.usermodel.HSSFCell;

import org.apache.poi.hssf.util.HSSFColor;

import org.apache.poi.ss.usermodel.Cell;

import org.apache.poi.ss.usermodel.CellStyle;

import org.apache.poi.ss.usermodel.Font;

import org.apache.poi.ss.usermodel.RichTextString;

import org.apache.poi.ss.usermodel.Row;

import org.apache.poi.ss.usermodel.Sheet;

import org.apache.poi.ss.usermodel.Workbook;

import org.apache.poi.ss.util.CellRangeAddress;

import org.apache.poi.ss.util.CellRangeAddressList;

import org.apache.poi.xssf.usermodel.XSSFCellStyle;

import org.apache.poi.xssf.usermodel.XSSFDataValidation;

import org.apache.poi.xssf.usermodel.XSSFDataValidationConstraint;

import org.apache.poi.xssf.usermodel.XSSFDataValidationHelper;

import org.apache.poi.xssf.usermodel.XSSFFont;

import org.apache.poi.xssf.usermodel.XSSFRichTextString;

import org.apache.poi.xssf.usermodel.XSSFSheet;

import org.apache.poi.xssf.usermodel.XSSFWorkbook;

public class ExcelDownloadUtil {

/**

* 标题单元格默认长度

*/

private static final int DEFAULT_COLUMN_SIZE = 20;

/**

* EXCEL含有下拉列表默认受影响行数

*/

private static final int SELECT_HEIGHT = 300;

/**

* 用于动态生成导出模板

*

* @param response 用于下载

* @param sheetName 工作表空间名称

* @param columnNames

* @param title Excle模板标题,不需要则传null

* @throws Exception

*/

public static void getExcelTitleTemplate(HttpServletResponse response, String sheetName,

List<Map<String, Object>> columnNames, String title) throws Exception {

Workbook workBook = new XSSFWorkbook();

// 生成一个表格

Sheet sheet = workBook.getSheet(sheetName);

if (sheet == null) {

sheet = workBook.createSheet(sheetName);

}

// 最新Excel列索引,从0开始

int lastRowIndex = sheet.getLastRowNum();

if (lastRowIndex > 0) {

lastRowIndex++;// 如果已经存在了工作表空间则从下一行开始

}

if (!StringUtils.isBlank(title)) {

// 如果需要合并单元格显示一个大的title

Row titleRow = sheet.createRow(lastRowIndex);

//参数说明:1.起始行号 2.终止行号 3.起始列号 4.终止列号

//这个需要实际情况自定义,我这里测试就写死0 0 0 4 了

CellRangeAddress region = new CellRangeAddress(0, 0, 0, 4);

sheet.addMergedRegion(region);// 合并单元格

Cell cellTiltle = titleRow.createCell(0);

// 设置样式

cellTiltle.setCellStyle(createCellHeadStyle(workBook, false));

// 单元格设置值

cellTiltle.setCellValue(title);

lastRowIndex++;

}

// 设置表格默认列宽度

sheet.setDefaultColumnWidth(DEFAULT_COLUMN_SIZE);

// 产生表格表头列标题行

Row row = sheet.createRow(lastRowIndex);

for (int i = 0; i < columnNames.size(); i++) {

Map<String, Object> map = columnNames.get(i);

Cell cell = row.createCell(i);

// 设置单元格类型

cell.setCellType(HSSFCell.CELL_TYPE_STRING);

// 设置单元格样式

cell.setCellStyle(createCellHeadStyle(workBook, (boolean)map.get("isSpecial")));

// 填充表头文本

RichTextString text = new XSSFRichTextString((String)map.get("columnname"));

cell.setCellValue(text);

String[] selectValue = (String[])map.get("selectValue");

// 如果需要有下拉列表则显示

if (selectValue != null && selectValue.length != 0) {

// 准备下拉列表数据

CellRangeAddressList regions = new CellRangeAddressList(1, SELECT_HEIGHT, i, i);

// 创建下拉列表数据

XSSFDataValidationHelper dvHelper = new XSSFDataValidationHelper((XSSFSheet)sheet);

XSSFDataValidationConstraint dvConstraint =

(XSSFDataValidationConstraint)dvHelper.createExplicitListConstraint(selectValue);

XSSFDataValidation validation = (XSSFDataValidation)dvHelper.createValidation(dvConstraint, regions);

validation.setSuppressDropDownArrow(true);

validation.setShowErrorBox(true);

sheet.addValidationData(validation);

}

}

OutputStream outputStream = response.getOutputStream();

workBook.write(outputStream);// HSSFWorkbook写入流,下载

outputStream.flush();// 刷新流

outputStream.close();// 关闭流

}

/**

* 创建单元格表头样式

*

* @param workbook 工作薄

* @param bgColorYellow true-背景使用黄色

* @return

*/

private static CellStyle createCellHeadStyle(Workbook workbook, boolean bgColorYellow) {

CellStyle style = workbook.createCellStyle();

// 设置边框样式

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);

// 生成字体

Font font = workbook.createFont();

// 表头样式

style.setFillPattern(XSSFCellStyle.SOLID_FOREGROUND);

// 如果是true,则显示黄色背景色

style.setFillForegroundColor(bgColorYellow ? HSSFColor.YELLOW.index : HSSFColor.GREY_25_PERCENT.index);

font.setFontHeightInPoints((short)12);

font.setBoldweight(XSSFFont.BOLDWEIGHT_BOLD);

// 把字体应用到当前的样式

style.setFont(font);

return style;

}

/**

* 得到有效的Excel文件列有效数据

*

* @param xianShiList

* @param biTianList

* @param jiGouId

* @return

*/

public static List<Map<String, Object>> getColumnNames(List<String> xianShiList, List<String> biTianList,

String condition) {

List<Map<String, Object>> columnNames = new ArrayList<Map<String, Object>>();

Map<String, Object> resultMap = null;

List<String> selectValues = null;

boolean validaBiTianList = biTianList != null && !biTianList.isEmpty();

for (int i = 0, len = xianShiList.size(); i < len; i++) {

resultMap = new HashMap<String, Object>();

// 得到下载的字段名称

String columnName = xianShiList.get(i);

// 判断该字段是否是字典类型,如果是字典类型的字段则需要显示下拉列表

// 我这里用了一个枚举类涵盖所有的可能涉及的下载字段,每次判断一下是否需要获取字典值

FieldEnum field = FieldEnum.getFieldEnum(columnName);

if (field != null) {

resultMap.put("columnname", columnName);

// 判断字段是否是必填字段

if (validaBiTianList && biTianList.contains(columnName)) {

resultMap.put("isSpecial", true);// 如果是必填则标识为true

} else {

resultMap.put("isSpecial", false);

}

if (field.isZiDian()) {// 如果是字典值

// 获取字典内容

// ZiDianEntity ziDian = ZiDianUtil.getZiDian(columnName, condition);

// List<ZiDianZhiEntity> ziDianZhiEntityList = ziDian.getZiDianZhiList();

selectValues = new ArrayList<>();

// 添加字典值到下拉列表

/*for (int j = 0, lenx = ziDianZhiEntityList.size(); j < lenx; j++) {

selectValues.add(ziDianZhiEntityList.get(j).getZiDianZhi());

}*/

// 这里为了测试直接写死了

selectValues.add("男");

selectValues.add("女");

selectValues.add("未知");

resultMap.put("selectValue", selectValues.toArray(new String[selectValues.size()]));

}

columnNames.add(resultMap);

}

}

return columnNames;

}

/**

* 得到EXCEL模板下载时的显示字段

*

* @param condition

* @return

* @throws Exception

*/

public static List<String> listXianShiField(String condition) throws Exception {

List<String> resultList = listExcelField("EXCEL下载时显示字段", condition);

resultList = resultList != null && resultList.size() != 0 ? resultList

: Arrays.asList(new String[] {"姓名", "身份证号", "性别", "联系电话", "联系地址"});

return resultList;

}

/**

* 得到EXCEL模板下载时的必填字段

*

* @param jiGouId

* @return

* @throws Exception

*/

public static List<String> listBiTianField(String jiGouId) throws Exception {

List<String> resultList = listExcelField("EXCEL必填字段", jiGouId);

resultList =

resultList != null && resultList.size() != 0 ? resultList : Arrays.asList(new String[] {"姓名", "性别"});

return resultList;

}

/**

* 通过设置名称获取显示list集合

*

* @param sheZhiMingCheng

* @param condition

* @return

* @throws Exception

*/

public static List<String> listExcelField(String sheZhiMingCheng, String condition) throws Exception {

List<String> list = null;

// 可以从数据库中动态获取,或者从程序中动态拼接出想要导出的字段

//do something

return list;

}

}

枚举类补充:

public enum FieldEnum {

/**

* 姓名

*/

XING_MING("姓名", false),

/**

* 身份证号

*/

SHEN_FEN_ZHENG_HAO("身份证号", false),

/**

* 性别

*/

XING_BIE("性别", true),

/**

* 婚姻状况

*/

HUN_YING_ZHUANG_KUANG("婚姻状况", true),

/**

* 联系人

*/

LIAN_XI_REN("联系人", false),

/**

* 联系电话

*/

LIAN_XI_DIAN_HUA("联系电话", false),

/**

* 联系地址

*/

LIAN_XI_DI_ZHI("联系地址", false);

/* 省略其他可能的属性 */

private String name;

private boolean isZiDian;

private FieldEnum(String name, boolean isZiDian) {

this.name = name;

this.isZiDian = isZiDian;

}

/**

* 通过name获取枚举类

*

* @param name

* @return

*/

public static FieldEnum getFieldEnum(String name) {

FieldEnum[] values = FieldEnum.values();

for (int i = 0; i < values.length; i++) {

if (values[i].getName().equals(name)) {

return values[i];

}

}

return null;

}

public String getName() {

return name;

}

public boolean isZiDian() {

return isZiDian;

}

}

3.实现下载:

/**

* 下载动态模板

*

* @param request

* @param response

*/

@RequestMapping(value = "/downloadDongTaiMuBan.do")

public void downloadDongTaiMuBan(HttpServletRequest request, HttpServletResponse response) {

try {

// 这里只是模仿一种条件,真正的条件需要根据实际情况传入

String condition = request.getRequestURL().toString();

System.out.println(condition);

// 根据条件从数据库动态获取需要导出的EXCEL字段

List<String> xianShiList = ExcelDownloadUtil.listXianShiField(condition);

if (xianShiList != null && !xianShiList.isEmpty()) {

// 根据条件从数据库动态获取必填的EXCEL字段

List<String> biTianList = ExcelDownloadUtil.listBiTianField(condition);

// 文件名编码,解决乱码问题

String fileName = "登记.xlsx";

String userAgentString = request.getHeader("User-Agent");

String browser = UserAgent.parseUserAgentString(userAgentString).getBrowser().getGroup().getName();

if (browser.equals("Chrome") || browser.equals("Internet Exploer") || browser.equals("Safari")) {

fileName = URLEncoder.encode(fileName, "utf-8").replaceAll("\\+", "%20");

} else {

fileName = MimeUtility.decodeText(fileName);

}

// 设置请求

response.setCharacterEncoding("UTF-8");

response.setContentType("application/x-download");

response.addHeader("Content-Disposition", String.format("attachment; filename=\"%s\"", fileName));

response.addHeader("Cache-Control", "no-cache, no-store, must-revalidate");

response.addHeader("Pragma", "no-cache");

response.addHeader("Expires", "0");

final String sheetName = "第一分组";// 设置EXCEL默认工作表空间名称

// 处理EXCEL字段,标识出需要必填的字段,有下拉列表的字段,获取下拉列表的值

List<Map<String, Object>> columnNames =

ExcelDownloadUtil.getColumnNames(xianShiList, biTianList, condition);

if (columnNames != null && !columnNames.isEmpty()) {

ExcelDownloadUtil.getExcelTitleTemplate(response, sheetName, columnNames, "登记信息");

}

}

} catch (Exception e) {

e.printStackTrace();

logger.error("生成下载动态模板异常!", e);

}

}

4.效果预览:


通过以上代码就简单实现Excle模板动态导出功能啦。

以上是 java动态导出Excle模板 的全部内容, 来源链接: utcz.com/z/390531.html

回到顶部