在实际开发中,由于业务需要,常常需要进行Excel导入导出操作。以前做一些简单的导入时,先准备一个模板,再进行导入,单有十几、

二十几个导入模板时,往往要做十几、二十几个模板。而且,当在模板中需要有下拉框,而且下拉数据要实时查询时,这样的方法就不太好了;

现在,做成了动态生成导入模板,只要参数传对了,就可以生成任何我们想要的导入模板,而且随意设置下拉框的数目、位置。

具体步骤如下:

1、需要用到的jar包:

poi-3.10-FINAL.jar

poi-ooxml-3.10-FINAL.jar

poi-ooxml-schemas-3.10-FINAL.jar

gradle引入:

compile group: 'org.apache.poi', name: 'poi', version: '3.10'
compile group: 'org.apache.poi', name: 'poi-ooxml', version: '3.10-FINAL'

2、生成Excel导入模板 :

/**
* @Title: createExcelTemplate
* @Description: 生成Excel导入模板
* @param @param filePath Excel文件路径
* @param @param handers Excel列标题(数组)
* @param @param downData 下拉框数据(数组)
* @param @param downRows 下拉列的序号(数组,序号从0开始)
* @return void
* @throws
*/
private static void createExcelTemplate(String filePath, String[] handers,
List<String[]> downData, String[] downRows){ HSSFWorkbook wb = new HSSFWorkbook();//创建工作薄 //表头样式
HSSFCellStyle style = wb.createCellStyle();
style.setAlignment(HSSFCellStyle.ALIGN_CENTER); // 创建一个居中格式
//字体样式
HSSFFont fontStyle = wb.createFont();
fontStyle.setFontName("微软雅黑");
fontStyle.setFontHeightInPoints((short)12);
fontStyle.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
style.setFont(fontStyle); //新建sheet
HSSFSheet sheet1 = wb.createSheet("Sheet1");
HSSFSheet sheet2 = wb.createSheet("Sheet2");
HSSFSheet sheet3 = wb.createSheet("Sheet3"); //生成sheet1内容
HSSFRow rowFirst = sheet1.createRow(0);//第一个sheet的第一行为标题
//写标题
for(int i=0;i<handers.length;i++){
HSSFCell cell = rowFirst.createCell(i); //获取第一行的每个单元格
sheet1.setColumnWidth(i, 4000); //设置每列的列宽
cell.setCellStyle(style); //加样式
cell.setCellValue(handers[i]); //往单元格里写数据
} //设置下拉框数据
String[] arr = {"A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"};
int index = 0;
HSSFRow row = null;
for(int r=0;r<downRows.length;r++){
String[] dlData = downData.get(r);//获取下拉对象
int rownum = Integer.parseInt(downRows[r]); if(dlData.length<5){ //255以内的下拉
//255以内的下拉,参数分别是:作用的sheet、下拉内容数组、起始行、终止行、起始列、终止列
sheet1.addValidationData(setDataValidation(sheet1, dlData, 1, 50000, rownum ,rownum)); //超过255个报错
} else { //255以上的下拉,即下拉列表元素很多的情况 //1、设置有效性
//String strFormula = "Sheet2!$A$1:$A$5000" ; //Sheet2第A1到A5000作为下拉列表来源数据
String strFormula = "Sheet2!$"+arr[index]+"$1:$"+arr[index]+"$5000"; //Sheet2第A1到A5000作为下拉列表来源数据
sheet2.setColumnWidth(r, 4000); //设置每列的列宽
//设置数据有效性加载在哪个单元格上,参数分别是:从sheet2获取A1到A5000作为一个下拉的数据、起始行、终止行、起始列、终止列
sheet1.addValidationData(SetDataValidation(strFormula, 1, 50000, rownum, rownum)); //下拉列表元素很多的情况 //2、生成sheet2内容
for(int j=0;j<dlData.length;j++){
if(index==0){ //第1个下拉选项,直接创建行、列
row = sheet2.createRow(j); //创建数据行
sheet2.setColumnWidth(j, 4000); //设置每列的列宽
row.createCell(0).setCellValue(dlData[j]); //设置对应单元格的值 } else { //非第1个下拉选项 int rowCount = sheet2.getLastRowNum();
//System.out.println("========== LastRowNum =========" + rowCount);
if(j<=rowCount){ //前面创建过的行,直接获取行,创建列
//获取行,创建列
sheet2.getRow(j).createCell(index).setCellValue(dlData[j]); //设置对应单元格的值 } else { //未创建过的行,直接创建行、创建列
sheet2.setColumnWidth(j, 4000); //设置每列的列宽
//创建行、创建列
sheet2.createRow(j).createCell(index).setCellValue(dlData[j]); //设置对应单元格的值
}
}
}
index++;
}
} try { File f = new File(filePath); //写文件 //不存在则新增
if(!f.getParentFile().exists()){
f.getParentFile().mkdirs();
}
if(!f.exists()){
f.createNewFile();
} FileOutputStream out = new FileOutputStream(f);
out.flush();
wb.write(out);
out.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}

3、设置有效性:

    /**
*
* @Title: SetDataValidation
* @Description: 下拉列表元素很多的情况 (255以上的下拉)
* @param @param strFormula
* @param @param firstRow 起始行
* @param @param endRow 终止行
* @param @param firstCol 起始列
* @param @param endCol 终止列
* @param @return
* @return HSSFDataValidation
* @throws
*/
private static HSSFDataValidation SetDataValidation(String strFormula,
int firstRow, int endRow, int firstCol, int endCol) { // 设置数据有效性加载在哪个单元格上。四个参数分别是:起始行、终止行、起始列、终止列
CellRangeAddressList regions = new CellRangeAddressList(firstRow, endRow, firstCol, endCol);
DVConstraint constraint = DVConstraint.createFormulaListConstraint(strFormula);
HSSFDataValidation dataValidation = new HSSFDataValidation(regions,constraint); dataValidation.createErrorBox("Error", "Error");
dataValidation.createPromptBox("", null); return dataValidation;
} /**
*
* @Title: setDataValidation
* @Description: 下拉列表元素不多的情况(255以内的下拉)
* @param @param sheet
* @param @param textList
* @param @param firstRow
* @param @param endRow
* @param @param firstCol
* @param @param endCol
* @param @return
* @return DataValidation
* @throws
*/
private static DataValidation setDataValidation(Sheet sheet, String[] textList, int firstRow, int endRow, int firstCol, int endCol) { DataValidationHelper helper = sheet.getDataValidationHelper();
//加载下拉列表内容
DataValidationConstraint constraint = helper.createExplicitListConstraint(textList);
//DVConstraint constraint = new DVConstraint();
constraint.setExplicitListValues(textList); //设置数据有效性加载在哪个单元格上。四个参数分别是:起始行、终止行、起始列、终止列
CellRangeAddressList regions = new CellRangeAddressList((short) firstRow, (short) endRow, (short) firstCol, (short) endCol); //数据有效性对象
DataValidation data_validation = helper.createValidation(constraint, regions);
//DataValidation data_validation = new DataValidation(regions, constraint); return data_validation;
}

4、下载指定路径的Excel文件:

 /**
* @Title: getExcel
* @Description: 下载指定路径的Excel文件
* @param @param url 文件路径
* @param @param fileName 文件名
* @param @param response
* @return void
* @throws
*/
public static void getExcel(String url, String fileName, HttpServletResponse response,HttpServletRequest request){ try { //1.设置文件ContentType类型,这样设置,会自动判断下载文件类型
response.setContentType("multipart/form-data"); //2.设置文件头:最后一个参数是设置下载文件名
response.setHeader("Content-disposition", "attachment; filename=\""
+ encodeChineseDownloadFileName(request, fileName+".xls") +"\"");
// response.setHeader("Content-Disposition", "attachment;filename="
// + new String(fileName.getBytes("UTF-8"), "ISO-8859-1") + ".xls"); //中文文件名 //通过文件路径获得File对象
File file = new File(url); FileInputStream in = new FileInputStream(file);
//3.通过response获取OutputStream对象(out)
OutputStream out = new BufferedOutputStream(response.getOutputStream()); int b = 0;
byte[] buffer = new byte[2048];
while ((b=in.read(buffer)) != -1){
out.write(buffer,0,b); //4.写到输出流(out)中
} in.close();
out.flush();
out.close(); } catch (IOException e) {
log.error("下载Excel模板异常", e);
}
} /**
*
* @Title: encodeChineseDownloadFileName
* @Description: TODO(这里用一句话描述这个方法的作用)
* @param @param request
* @param @param pFileName
* @param @return
* @param @throws UnsupportedEncodingException
* @return String
* @throws
*/
private static String encodeChineseDownloadFileName(HttpServletRequest request, String pFileName)
throws UnsupportedEncodingException { String filename = null;
String agent = request.getHeader("USER-AGENT");
//System.out.println("agent==========》"+agent); if (null != agent) {
if (-1 != agent.indexOf("Firefox")) {//Firefox
filename = "=?UTF-8?B?" + (new String(org.apache.commons.codec.binary.Base64.encodeBase64(pFileName.getBytes("UTF-8")))) + "?=";
} else if (-1 != agent.indexOf("Chrome")) {//Chrome
filename = new String(pFileName.getBytes(), "ISO8859-1");
} else {//IE7+
filename = java.net.URLEncoder.encode(pFileName, "UTF-8");
filename = StringUtils.replace(filename, "+", "%20");//替换空格
}
} else {
filename = pFileName;
} return filename;
}

5、删除生成的临时文件:

/**
* @Title: delFile
* @Description: 删除文件
* @param @param filePath 文件路径
* @return void
* @throws
*/
public static void delFile(String filePath) {
java.io.File delFile = new java.io.File(filePath);
delFile.delete();
}

6、示例:

/**
* @Title: getExcelTemplate
* @Description: 生成Excel模板并导出
* @param @param uuid
* @param @param request
* @param @param response
* @param @return
* @return Data
* @throws
*/
@RequestMapping("/getExcelTemplate")
public void getExcelTemplate(HttpServletRequest request, HttpServletResponse response){ String fileName = "员工信息表"; //模板名称
String[] handers = {"姓名","性别","证件类型","证件号码","服务结束时间","参保地","民族"}; //列标题 //下拉框数据
List<String[]> downData = new ArrayList();
String[] str1 = {"男","女","未知"};
String[] str2 = {"北京","上海","广州","深圳","武汉","长沙","湘潭"};
String[] str3 = {"01-汉族","02-蒙古族","03-回族","04-藏族","05-维吾尔族","06-苗族","07-彝族","08-壮族","09-布依族",
              "10-朝鲜族","11-满族","12-侗族","13-瑶族","14-白族","15-土家族","16-哈尼族","17-哈萨克族","18-傣族","19-黎族","20-傈僳族",
              "21-佤族","22-畲族","23-高山族","24-拉祜族","25-水族","26-东乡族","27-纳西族","28-景颇族","29-柯尔克孜族","30-土族",
              "31-达斡尔族","32-仫佬族","33-羌族","34-布朗族","35-撒拉族","36-毛难族","37-仡佬族","38-锡伯族","39-阿昌族","40-普米族",
              "41-塔吉克族","42-怒族","43-乌孜别克族","44-俄罗斯族","45-鄂温克族","46-德昂族","47-保安族","48-裕固族","49-京族","50-塔塔尔族",
              "51-独龙族","52-鄂伦春族","53-赫哲族","54-门巴族","55-珞巴族","56-基诺族","98-外国血统","99-其他"};
downData.add(str1);
downData.add(str2);
downData.add(str3);
String [] downRows = {"1","5","6"}; //下拉的列序号数组(序号从0开始) try { ExcelUtil.getExcelTemplate(fileName, handers, downData, downRows, request, response); } catch (Exception e) {
log.error("批量导入信息异常:" + e.getMessage());
}
}

7、结果如图:

java动态生成带下拉框的Excel导入模板的更多相关文章

  1. jQuery动态生成<select>下拉框

    前一阵在项目里需要动态生成下拉框,找了一下用jQuery实现比较方便,这里整理一下. 下文所述方法只是本人在项目中遇到问题的解决方法,场景较为简单,也希望能帮助有需要的朋友 1.动态生成下拉框的两种方 ...

  2. angularjs小练习(分别通过ng-repeat和ng-option动态生成select下拉框)

    本次做一个简单的关于动态生成select的练习 在实现上有两种方式: 其一.通过ng-repeat来实现 其二.通过ng-option来实现 在页面效果上,两种实现的效果都一样 但是在数据选择的数据从 ...

  3. 《手把手教你》系列技巧篇(三十二)-java+ selenium自动化测试-select 下拉框(详解教程)

    1.简介 在实际自动化测试过程中,我们也避免不了会遇到下拉选择的测试,因此宏哥在这里直接分享和介绍一下,希望小伙伴或者童鞋们在以后工作中遇到可以有所帮助. 2.select 下拉框 2.1Select ...

  4. POI 生成带联动下拉框的excel表格

    参考:https://www.cnblogs.com/cjbbk/p/7527276.html 解决POI3.17 与其它版本的不同的坑:https://blog.csdn.net/Weirdo_zh ...

  5. java导入导出下载Excel,xls文件(带下拉框)

    /** * 导入excel文件 * 2014-7-23 * @return */ @RequiresPermissions("plug:product:caiwu:upload") ...

  6. excel 如何制作带下拉框的动态折线图表

    首先我们需要有个类似下图产品销量的基础数据表. 首先将光标放入表格中任意位置,然后插入一个不带点标记的折线图,然后将折线的颜色设置为灰色. 第一次设置成灰色后,一定善用f4快捷键进行快速的折线颜色设置 ...

  7. 动态加载下拉框列表并添加onclick事件

    1.  js动态加载元素并设置属性 摘自(http://www.liangshunet.com/ca/201408/336848696.htm) <div id="parent&quo ...

  8. 动态改变ComboBox下拉框的宽度

    在C++Builder中有时下拉框的内容比较长,标准长度下根本显示不完,可以调用PostMessage()方法来实现 ::PostMessage(comb->Handle,CB_SETDROPP ...

  9. 【jquery】ajax 动态 改变 select下拉框选中的值

    //JS<script type="text/javascript> //ajax动态给添加原料的[商品名称]下拉框绑定selected属性 $("#origin_co ...

随机推荐

  1. 信息安全系统设计基础实验五:简单嵌入式 WEB 服务器实验 (20135229,20135234)

    http://www.cnblogs.com/mqy123/p/5002683.html

  2. jQuery问题:$XXX is not a function

    用火狐浏览器打开,js代码一段不执行,F12以后看见下面的错误: 网上查看说是jQuery文件引用的问题,把jQuery.js引入语句修改了一下,果然没有错了. 我原来的引用语句是:<scrip ...

  3. [POJ3177]Redundant Paths(双联通)

    在看了春晚小彩旗的E技能(旋转)后就一直在lol……额抽点时间撸一题吧…… Redundant Paths Time Limit: 1000MS   Memory Limit: 65536K Tota ...

  4. ThinkPHP中的跨控制器调用与框架执行流程

    一.跨控制器调用 UserController.class.php <?php namespace Home/Controller use Think/Controller class User ...

  5. FileStream大文件复制

    FileStream缓冲读取和写入可以提高性能.FileStream读取文件的时候,是先讲流放入内存,经Flash()方法后将内存中(缓冲中)的数据写入文件.如果文件非常大,势必消耗性能.特封装在Fi ...

  6. 每天一个linux命令(7):cp 命令

    cp 命令用来复制文件或者目录,是Linux系统中最常用的命令之一.一般情况下,shell会设置一个别名,在命令行下复制文件时,如果目标文件已经存在, 就会询问是否覆盖,不管你是否使用-i参数.但是如 ...

  7. nslog

    今天有人问我怎么更好的使用nslog,打包的时候老注释 pch里加下面的代码就好了平时debug的时候打印,release后就不打印了 #ifdef DEBUG#define NSLog(...) N ...

  8. 常用sql,在做项目时用mysqlWorkBeach里面自动生成的

    -- 修改表中的字段的长度ALTER TABLE `sfkbbs`.`sfk_father_module` CHANGE ) NULL DEFAULT NULL COMMENT '父板块名字' ; 在 ...

  9. 洛谷P2507 [SCOI2008]配对

    题目背景 四川NOI2008省选 题目描述 你有 n 个整数Ai和n 个整数Bi.你需要把它们配对,即每个Ai恰好对应一个Bp[i].要求所有配对的整数差的绝对值之和尽量小,但不允许两个相同的数配对. ...

  10. Dedecms include\dialog\select_soft_post.php Upload Any Files To The Specified Directory Via Variable Not Initial Flaw Bypass Extension Defence

    目录 . 漏洞描述 . 漏洞触发条件 . 漏洞影响范围 . 漏洞代码分析 . 防御方法 . 攻防思考 1. 漏洞描述 综合来说,这个漏洞的根源是"register_globals = on& ...