放到工程的lib文件夹下.本文中项目所使用的jar包为:
前台用easyui框架(这里博主用的是easyui框架,其他框架道理一样),选中一条数据,进行方案导出.效果截图如下:
首先是先获取选中方案的id(数据库中的),根据此id去数据库中查询方案下包含的具体的自定义媒体类型信息列表.用于封装成excel的基础数据,也就是要导出的内容.利用poi导出excel大体思路:
1,需要导出的原始数据.即根据实际需求查询得到的结果集作为原始数据.可能是一个list,map...看你封装成什么样了(这里是封装成list了)
2,将原始的数据转换到excel中,具体根据数据形式不同,写法也会不同.不过这些都是大同小异的.
3,将生产好的excel文件写到一个路径下(这里都是放到tomcat服务器目录下的download下).
4,根据上一步的路径找到excel文件进行下载操作(就是文件下载...网上一大片)
下面看各个层的代码,以及excel工具类.具体步骤,代码中注释已经写到很明白了.
Controller层代码:
/**
* 导出新闻方案
* @param Integer[] newsScheme方案id数组
* @throws Exception
*/
@RequestMapping(value = "newsSchemes/export/{newsSchemesId}",method = RequestMethod.POST)
public void exportNewsScheme(@PathVariable("newsSchemesId") Integer newsSchemesId) throws Exception{
System.err.println("导出的方案的id:"+newsSchemesId);
//切换到rsdb数据库
DataSourceContextHolder.setDbType(DataSourceType.SOURCE_RSDB);
//查询的结果集,list为需要在表格中展示的数据
List list = this.newsMediaCategoryService.listNewsMediaCateBySid(new NewsMediaCategory(newsSchemesId));
//循环将自定义媒体对应的新闻源集合存入到list中.
if(list != null && list.size()>0){
for(int i=0;i siteList = this.siteService.listBySids(new Site(sIds));
//List site = this.siteMapper.listBySids(null)
list.get(i).setSiteList(siteList);
list.get(i).setSids(sIds);
}
}
for(NewsMediaCategory nmc : list){
System.err.println(nmc.getName()+"--------"+nmc.getSiteList().size());
}
//切换到rsdb数据库
DataSourceContextHolder.setDbType(DataSourceType.SOURCE_RSDB);
//根据方案id查询方案基本信息,主要是为了获取导出时候的默认名为(当前方案名+时间戳)
NewsSchemes newsScheme = this.newsSchemesService.selNewsSchemesBySchemesId(newsSchemesId);
//获取欲下载的文件路径
String filePath =this.newsSchemesService.createNewSchemesExcel(newsScheme,list,this.request);
//执行下载操作
ExcelUtils.download(filePath , this.request , this.response);
}
service层代码:
这里需要说明下:步骤大体是这么搞,但是样式需要根据不同需求来设定,其中的逻辑也会不一样的.此处导出的样式如下图:
代码如下:
/**
* 方法描述:生产方案excel文件,并写到指定位置.将该文件的绝对路径返回
* 返回类型:String
* 作者:GQ
* 创建时间:2016年12月30日14:41:52
* @param request request请求
* @param newsSchemeId 新闻方案id
* @param list NewsMediaCategory集合
*/
@Override
public String createNewSchemesExcel(NewsSchemes newsScheme,List list,HttpServletRequest request) {
// 第一步,创建一个workbook,对应一个Excel文件
HSSFWorkbook wb = new HSSFWorkbook();
// 第二步,在workbook中添加一个sheet,对应Excel文件中的sheet
HSSFSheet sheet = wb.createSheet("新闻方案表");
//获取单元格格式的样式,一些基本属性
HSSFCellStyle cellStyle = ExcelUtils.getCellStyle(wb);
//获取标题格式
HSSFCellStyle titleStyle = ExcelUtils.getTitleStyle(wb);
//创建表头.第一行.第一列的数据
ExcelUtils.createCell(sheet, 0, 0, titleStyle, "方案具体信息表");
//合并单元格CellRangeAddress构造参数依次表示起始行,截至行,起始列, 截至列
ExcelUtils.mergedRegion(sheet , 0 , 0 , 0 , 2);
//第二行,弟1,2,3列对应的数值,创建行"自定义媒体名称,备注信息,包含站点源个数".
ExcelUtils.createMultiCell(sheet , 1 , new Integer[]{0,1,2} , cellStyle , new String[]{"自定义媒体名称","备注信息","包含站点源个数"});
//记录第一个总信息表真实数据行数,真实数据添加的起始行应该是(rCounts-1)为真是数据起始行.
int rCounts=3;
//将真实数据插入到excel表中去.
for (int r = 0; r < list.size(); r++) {
//获取真实数据
NewsMediaCategory nmc = list.get(r);
//每次填充同一行的,前三个单元格.调用同时填充(同一行的多个单元格的方法).
ExcelUtils.createMultiCell(sheet , r+2 , new Integer[]{0,1,2} , cellStyle , new String[]{nmc.getName(),nmc.getRemark(),String.valueOf(nmc.getSiteList().size())});
//每次加1,为了得到下一个表的表头位置.
rCounts++;
}
//设置分割那一行,将他创建出来,但是不赋值任何数据,用于导入时候的区分点.
ExcelUtils.createRow(sheet , rCounts-1);
//System.err.println("rowNullde的单元格个数:"+rowNull.getPhysicalNumberOfCells());
//设置'自定义媒体类型具体信息表',表头
ExcelUtils.createCell(sheet, rCounts, 0, titleStyle, "自定义媒体类型具体信息表");
//累计,判断合并时候用.确定每一个单元格
int m=0;
for (int r = 0; r < list.size(); r++) {
//循环控制有几个媒体类型
NewsMediaCategory nmc = list.get(r);
//合并自定义媒体名称那一行,m控制合并的起止位置.
ExcelUtils.mergedRegion(sheet , rCounts+1 , rCounts+1 , m , m+2);
//设置自定义媒体名称那一行,每一个单元格名称.
ExcelUtils.createMultiCell(sheet , rCounts+1 , new Integer[]{m,m+1,m+2} , cellStyle , new String[]{nmc.getName(),"",""});
//循环出媒体名称下面的哪一行,"新闻源id,新闻源站点名称,url"
ExcelUtils.createMultiCell(sheet , rCounts+2 , new Integer[]{m,m+1,m+2} , cellStyle , new String[]{"新闻源id","新闻源站点名称","url"});
//填充,每一个自定义媒体类型下,所拥有的新闻源具体信息..
for(int i=0;i
excel的工具类:(等读者熟悉了,自己写自己合适的工具类这里多有东西只是起到指引作用).
package com.rs.sys.utils;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFRichTextString;
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.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.CellRangeAddress;
import org.springframework.web.multipart.MultipartFile;
/**
* 处理excel文件的工具类
* @author GQ
* @date 2016年12月27日 上午10:39:56
* @status
*/
public class ExcelUtils {
/**
* 方法描述:用于下载文件,根据存在的文件绝对路径下载.
* 返回类型:void
* 作者:GQ
* 创建时间:2016年12月27日上午10:51:17
* @param filePath 欲下载的文件绝对路径.
如:"F:\apache-tomcat-7.0.70\webapps\Rs_sys\WEB-INF\download\xxx.xls"
* @param request request请求
* @param response response请求
*/
public static void download(String filePath,HttpServletRequest request,HttpServletResponse response){
HSSFWorkbook workbook=null;
ServletOutputStream sos=null;
try {
File file = new File(filePath);
if (!file.exists()) {
response.sendError(404, "File not found!");
return;
}
BufferedInputStream br = new BufferedInputStream(new FileInputStream(
filePath));
String downLoadName = null;
String agent = request.getHeader("USER-AGENT");
if (null != agent && -1 != agent.indexOf("MSIE")) // IE
{
downLoadName = java.net.URLEncoder.encode(file.getName(), "UTF-8");
} else if (null != agent && -1 != agent.indexOf("Mozilla")) // Firefox
{
downLoadName = new String(file.getName().getBytes("UTF-8"),
"iso-8859-1");
} else {
downLoadName = java.net.URLEncoder.encode(file.getName(), "UTF-8");
}
byte[] buf = new byte[1024];
int len = 0;
response.reset();
response.setContentType("application/vnd.ms-excel;charset=UTF-8");
response.setHeader("Content-Disposition", "attachment; filename="
+ downLoadName);
OutputStream out = response.getOutputStream();
while ((len = br.read(buf)) > 0) {
out.write(buf, 0, len);
}
br.close();
out.close();
}catch (Exception e) {
e.printStackTrace();
}finally{
try {
if (null != workbook) {
workbook.close();
}
if(null!=sos){
sos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 方法描述:获取单元格中的数据,根据存储的值的类型不同,调用相应的方法获取数据,最后返回一个字符串类型的数据
* 返回类型:String
* 作者:GQ
* 创建时间:2016年12月28日下午6:24:00
* @param cell 单元格
* @return
*/
public static String getCellValue(Cell cell) {
String cellValue = "";
//DecimalFormat df = new DecimalFormat("#");
switch (cell.getCellType()) {
case HSSFCell.CELL_TYPE_STRING:
cellValue = cell.getRichStringCellValue().getString().trim();
break;
case HSSFCell.CELL_TYPE_NUMERIC:
cellValue = String.valueOf(new Integer((int)cell.getNumericCellValue()));
break;
case HSSFCell.CELL_TYPE_BOOLEAN:
cellValue = String.valueOf(cell.getBooleanCellValue()).trim();
break;
case HSSFCell.CELL_TYPE_FORMULA:
cellValue = cell.getCellFormula();
break;
default:
cellValue = "";
}
return cellValue;
}
/**
* 方法描述:文件写入
* 返回类型:void
* 作者:GQ
* 创建时间:2016年12月30日下午1:41:24
* @param file 为获得到的文件(也就是要讲这个文件写到哪里)
* @param filePath 文件写入的位置
* @param fileName
文件的名
*/
public static void write(MultipartFile file,String filePath,String fileName){
//在指定目录下建立一个空的文件,作用:别的file文件往里写入
File targetFile = new File(filePath, fileName);
if(!targetFile.exists()){
targetFile.mkdirs();
}
//保存
try {
//将前台传过来的file文件写到targetFile中.
file.transferTo(targetFile);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 方法描述:创建行,rowNum控制创建第几行.sheet控制在哪个工作簿上创建
* 返回类型:HSSFRow
* 作者:GQ
* 创建时间:2017年1月3日下午4:58:09
* @param sheet 工作簿
* @param rowNum 行数(下标从0开始)
* @return
*/
public static HSSFRow createRow(HSSFSheet sheet,int rowNum) {
return sheet.getRow(rowNum)!=null?sheet.getRow(rowNum):sheet.createRow(rowNum);
}
/**
* 方法描述:创建一个cell,样式,值.
* 返回类型:void
* 作者:GQ
* 创建时间:2017年1月3日下午4:02:32
* @param cellnum 第几个cell,下标从0开始,即0代表第一个
* @param value 该cell的值
* @param row 行
* @param style 样式(采用哪个样式)
*/
public static HSSFCell createCell(HSSFSheet sheet, int rowNumm, int cellNum, HSSFCellStyle style, String value) {
HSSFRow row = createRow(sheet,rowNumm);
HSSFCell cell = row.createCell((short) cellNum);
cell.setCellValue(new HSSFRichTextString(value));
cell.setCellStyle(style);
return cell;
}
/**
* 方法描述:创建多个单元格.必须是同一行的.并赋值上相应数据
* 返回类型:HSSFCell
* 作者:GQ
* 创建时间:2017年1月3日下午5:21:52
* @param sheet 工作簿
* @param rowNumm 行数
* @param cellNums 要创建的单元格下标数组
* @param style 样式
* @param values 单元格下标对应的值,一个对应一个,顺序不能乱
*/
public static List createMultiCell(HSSFSheet sheet, int rowNumm, Integer[] cellNums, HSSFCellStyle style, String[] values) {
List cellList = new ArrayList();
for(int i=0;i
* 返回类型:HSSFCellStyle
* 作者:GQ
* 创建时间:2017年1月3日下午4:04:02
* @param workbook
*/
public static HSSFCellStyle getCellStyle(HSSFWorkbook workbook) {
/*//设置字体;
HSSFFont font = workbook.createFont();
//设置字体大小;
font.setFontHeightInPoints((short) 5);
//设置字体名字;
font.setFontName("Courier New");*/
//font.setItalic(true);
//font.setStrikeout(true);
//设置样式;
HSSFCellStyle style = workbook.createCellStyle();
//设置底边框;
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.setFont(font);
//设置自动换行;
style.setWrapText(true);
//设置水平对齐的样式为居中对齐;
style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
//设置垂直对齐的样式为居中对齐;
style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
return style;
}
/**
* 方法描述:自定义设置标题样式,只有下边框
* 返回类型:HSSFCellStyle
* 作者:GQ
* 创建时间:2017年1月3日下午4:20:42
* @param workbook
*/
public static HSSFCellStyle getTitleStyle(HSSFWorkbook workbook){
HSSFCellStyle style = workbook.createCellStyle();
style.setAlignment(HSSFCellStyle.ALIGN_CENTER); // 创建一个居中格式
// 设置标题只有下边框
style.setBorderBottom(HSSFCellStyle.BORDER_THIN);
return style;
}
/**
* 方法描述:合并单元格
* 返回类型:int
* 作者:GQ
* 创建时间:2017年1月4日上午10:45:20
* @param sheet 工作簿
* @param firstRow 合并起止行(下标从0开始)
* @param lastRow 合并截止行(下标从0开始)
* @param firstCol 合并起止列(下标从0开始)
* @param lastCol 合并截止列(下标从0开始)
*/
public static int mergedRegion(HSSFSheet sheet,int firstRow, int lastRow, int firstCol, int lastCol){
return sheet.addMergedRegion(new CellRangeAddress(firstRow,lastRow,firstCol,lastCol));
}
/**
* 方法描述:将生成好的excel文件,写入到指定路径下的文件中.
* 返回类型:void
* 作者:GQ
* 创建时间:2017年1月4日上午10:57:04
* @param wb 一个workbook,对应一个Excel文件
* @param absolutePath excel文件的绝对路径
*/
public static void writeExcelToLocation(HSSFWorkbook wb,String absolutePath){
try {
FileOutputStream fout = new FileOutputStream(absolutePath);
wb.write(fout);
fout.close();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 方法描述:获取workbook,将文件转换为workbook对象
* 返回类型:Workbook
* 作者:GQ
* 创建时间:2017年1月4日下午5:12:20
* @param absolutePath 文件的绝对路径(excel文件)
* @return
*/
public static Workbook getWorkBook(String absolutePath){
FileInputStream fis =null;
Workbook wb = null;
try{
// 获取一个绝对地址的流
fis = new FileInputStream(absolutePath);
wb = new HSSFWorkbook(fis);
}catch(IOException e){
// TODO Auto-generated catch block
e.printStackTrace();
}
return wb;
}
}
前台需要注意:
用的是表单提交.代码如下:
js代码:
//返回被选中的行数据,没有则返回空
var rows = $('#news_scheme_manage').datagrid('getSelections');
if(rows!=null && rows.length==1){
var row = $('#news_scheme_manage').datagrid('getSelected');
//id用于查询方案对应的类型
var id=row.id;
console.log("id:"+id);
//到弹出框中进行编辑
//类选择器获取表单.
var form = $( "#news_scheme_manage_excel_export" );
//设置表单中的相应属性
//设置提交方式为post.
form.attr( "method", "post" );
//设置提交按钮跳转地址
form.attr( "action", "newsSchemes/export/"+id );
//若以上判断返回非false则表单提交.
form.submit();
}else{ //选中多条或者没有选则弹出提示信息 $.messager.alert("提示信息","有且只能选择一条数据!","info"); }
特殊声明:博主第一次写,格式什么的不要介意,只是自己的一个笔记,有些地方可能说的不是很明白,可能存在很多漏洞或者bug,还望多多包涵.希望会给刚入门的同学一点点启示作用.谢谢