首次接触POI,准备把这次经历记录下来。先介绍导出的功能:
首先是针对前端的利用ajax请求
<a href="javascript:printFInfo()" class="easyui-linkbutton"
data-options="iconCls:'icon-print'">导出</a>
----------------------------------------------------------------------------
<script type="text/javascript">
function printFInfo(){
$.ajax({
type:"post",
url:"${ctx }/bom/bomExport.do",
data : {
billNo : billNO
},
dataType : "json",
success:function(data){
if(data=="1"){
$.messager.show({
title : '提示:',
msg : '导出成功!文件在桌面 O ~ ~'
});
}else{
$.messager.show({
title : '提示:',
msg : '导出失败!请联系管理员。'
});
}
}
});
}
</script>
直接跳到service层
@Override
public void bomExport(String billNo) {
//获取需导出的数据
List<OrderBom> orderBoms = orderBomDao.getBomInfos(billNo);
// 生成表格标题行
String[] headers = { "分级层次", "生产订单号", "物料代码", "物料名称", "规格型号", "物料属性", "单位", "用量", "损耗", "净重", "供应商", "计划跟踪号",
"计划模式" };
// -----设置导出表格-----
// 声明一个工作薄
HSSFWorkbook workbook = new HSSFWorkbook();
// 生成一个表格
HSSFSheet sheet = workbook.createSheet("订单BOM信息");
// 设置表格默认列宽度为15个字节
sheet.setDefaultColumnWidth(15);
sheet.autoSizeColumn(1, true);
// 生成一个样式
HSSFCellStyle style = workbook.createCellStyle();
// 设置这些样式
style.setAlignment(HSSFCellStyle.ALIGN_LEFT);
style.setVerticalAlignment(org.apache.poi.ss.usermodel.CellStyle.VERTICAL_CENTER);
style.setBorderBottom(HSSFCellStyle.BORDER_THIN);
style.setBorderLeft(HSSFCellStyle.BORDER_THIN);
style.setBorderRight(HSSFCellStyle.BORDER_THIN);
style.setBorderTop(HSSFCellStyle.BORDER_THIN);
// 生成一个字体
HSSFFont font = workbook.createFont();
font.setFontHeightInPoints((short) 12);
font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
// 把字体应用到当前的样式
style.setFont(font);
// 生成并设置另一个样式
HSSFCellStyle style2 = workbook.createCellStyle();
style2.setBorderBottom(HSSFCellStyle.BORDER_THIN);
style2.setBorderLeft(HSSFCellStyle.BORDER_THIN);
style2.setBorderRight(HSSFCellStyle.BORDER_THIN);
style2.setBorderTop(HSSFCellStyle.BORDER_THIN);
// 生成另一个字体
HSSFFont font2 = workbook.createFont();
font2.setFontName("宋体");
// 把字体应用到当前的样式
style2.setFont(font2);
// 产生表格标题行
HSSFRow row = sheet.createRow(0);
row.setHeightInPoints(30);
for (int k = 0; k < headers.length; k++) {
HSSFCell cell = row.createCell(k);
cell.setCellStyle(style);
HSSFRichTextString text = new HSSFRichTextString(headers[k]);
cell.setCellValue(text);
}
// 写入查询数据,并设置样式
for (OrderBom orderBom : orderBoms) {
int lastRowNum = sheet.getLastRowNum() + 1;// 当前需要增加行的下标
row = sheet.createRow(lastRowNum);
row.setHeightInPoints(20);
row.createCell(0).setCellValue(orderBom.getFlevel());
row.createCell(1).setCellValue(billNo);
row.createCell(2).setCellValue(orderBom.getFnumber());
row.createCell(3).setCellValue(orderBom.getFname());
row.createCell(4).setCellValue(orderBom.getFmodel());
row.createCell(5).setCellValue(orderBom.getFattribute());
row.createCell(6).setCellValue(orderBom.getFunit());
row.createCell(7).setCellValue(orderBom.getFdosage());
row.createCell(8).setCellValue(orderBom.getFloss());
row.createCell(9).setCellValue(orderBom.getFnetWeight());
row.createCell(10).setCellValue(orderBom.getFsupplier());
row.createCell(11).setCellValue(orderBom.getFplanNum());
row.createCell(12).setCellValue(orderBom.getFplanMode());
for (int j = 0; j < headers.length; j++) {
row.getCell(j).setCellStyle(style2);
}
}
// 将文件存储到指定位置
// 获取桌面路径
FileSystemView fsv = FileSystemView.getFileSystemView();
String desktop = fsv.getHomeDirectory().getPath();
String filePath = desktop + "/报关BOM信息." + time + ".xls";
File file = new File(filePath);
FileOutputStream fout = new FileOutputStream(file);
try {
workbook.write(fout);
fout.flush();
fout.close();
} catch (Exception e) {
e.printStackTrace();
}
}
这就能完成简单的导出文件,需要注意的是这种自动获取路径的方式,有缺陷!只能下载在服务器的桌面路径,所以测试用这种方式可以,但是实际还是要让用户自己选择路径下载,这就不能用ajax了。接下来介绍另一种:
//打印报表信息
function printFInfo(){
if(billNO!=null){
location.href="${ctx }/bom/bomInfosPrint.do?billNo="+billNO;
}
}
在Controller层用request获取参数
/**
* 订单BOM信息导出
*
* @return
*/
@RequestMapping({ "bomInfosPrint.do" })
@ResponseBody
public void bomInfosPrint(HttpServletResponse response, HttpServletRequest request) {
// 切换数据库
String billNo = request.getParameter("billNo").toString();
CustomerContextHolder.setCustomerType("mssqlDataSource");
orderBomService.bomExport(billNo, response);
CustomerContextHolder.clearCustomerType();
}
这是service层的内容。
@Override
public void bomExport(String billNo, HttpServletResponse response) {
List<OrderBom> orderBoms = orderBomDao.getBomInfos(billNo);
// 生成表格标题行
String[] headers = { "分级层次", "生产订单号", "物料代码", "物料名称", "规格型号", "物料属性", "单位", "用量", "损耗", "净重", "供应商", "计划跟踪号",
"计划模式" };
// -----设置导出表格-----
// 声明一个工作薄
HSSFWorkbook workbook = new HSSFWorkbook();
// 生成一个表格
HSSFSheet sheet = workbook.createSheet("订单BOM信息");
// 设置表格默认列宽度为15个字节
sheet.setDefaultColumnWidth(15);
sheet.autoSizeColumn(1, true);
// 生成一个样式
HSSFCellStyle style = workbook.createCellStyle();
// 设置这些样式
style.setAlignment(HSSFCellStyle.ALIGN_LEFT);
style.setVerticalAlignment(org.apache.poi.ss.usermodel.CellStyle.VERTICAL_CENTER);
style.setBorderBottom(HSSFCellStyle.BORDER_THIN);
style.setBorderLeft(HSSFCellStyle.BORDER_THIN);
style.setBorderRight(HSSFCellStyle.BORDER_THIN);
style.setBorderTop(HSSFCellStyle.BORDER_THIN);
// 生成一个字体
HSSFFont font = workbook.createFont();
font.setFontHeightInPoints((short) 12);
font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
// 把字体应用到当前的样式
style.setFont(font);
// 生成并设置另一个样式
HSSFCellStyle style2 = workbook.createCellStyle();
style2.setBorderBottom(HSSFCellStyle.BORDER_THIN);
style2.setBorderLeft(HSSFCellStyle.BORDER_THIN);
style2.setBorderRight(HSSFCellStyle.BORDER_THIN);
style2.setBorderTop(HSSFCellStyle.BORDER_THIN);
// 生成另一个字体
HSSFFont font2 = workbook.createFont();
font2.setFontName("宋体");
// 把字体应用到当前的样式
style2.setFont(font2);
// 产生表格标题行
HSSFRow row = sheet.createRow(0);
row.setHeightInPoints(30);
for (int k = 0; k < headers.length; k++) {
HSSFCell cell = row.createCell(k);
cell.setCellStyle(style);
HSSFRichTextString text = new HSSFRichTextString(headers[k]);
cell.setCellValue(text);
}
// 写入查询数据,并设置样式
for (OrderBom orderBom : orderBoms) {
int lastRowNum = sheet.getLastRowNum() + 1;// 当前需要增加行的下标
row = sheet.createRow(lastRowNum);
row.setHeightInPoints(20);
row.createCell(0).setCellValue(orderBom.getFlevel());
row.createCell(1).setCellValue(billNo);
row.createCell(2).setCellValue(orderBom.getFnumber());
row.createCell(3).setCellValue(orderBom.getFname());
row.createCell(4).setCellValue(orderBom.getFmodel());
row.createCell(5).setCellValue(orderBom.getFattribute());
row.createCell(6).setCellValue(orderBom.getFunit());
row.createCell(7).setCellValue(orderBom.getFdosage());
row.createCell(8).setCellValue(orderBom.getFloss());
row.createCell(9).setCellValue(orderBom.getFnetWeight());
row.createCell(10).setCellValue(orderBom.getFsupplier());
row.createCell(11).setCellValue(orderBom.getFplanNum());
row.createCell(12).setCellValue(orderBom.getFplanMode());
for (int j = 0; j < headers.length; j++) {
row.getCell(j).setCellStyle(style2);
}
}
// 创建response输出流
SimpleDateFormat df = new SimpleDateFormat("yyMMdd-HH.mm");// 设置日期格式
String time = df.format(new Date());// new Date()为获取当前系统时间
OutputStream os = null;
try {
os = response.getOutputStream();
} catch (IOException e1) {
e1.printStackTrace();
}
response.reset();
String filename = "订单BOM信息." + time + ".xls";
response.setContentType("application/msexcel");
try {
response.setHeader("Content-disposition", "attachment; filename=" + URLEncoder.encode(filename, "UTF-8"));
workbook.write(os);
os.flush();
os.close();
} catch (Exception e) {
e.printStackTrace();
}
}
这样子就可以让用户自己选择下载路径了。
做项目时有一个需求,数据做成树形结构后只取它最下阶导出,我刚开始用了很多个if判断,后来发现不对劲,做了一个递归循环,记录一下:
@Override
public void customBomExport(String billNo, HttpServletResponse response) {
// 获取数据
List<OrderBom> orderBoms = orderBomDao.getBomInfos(billNo);
List<OrderBom> product = new ArrayList<OrderBom>();
Double k = null;
int indexOf = 0;
for (OrderBom orderBom : orderBoms) {
if (orderBom.get_parentId() == null) {
indexOf = orderBoms.indexOf(orderBom);
k = orderBom.getFdosage();
product.add(orderBom);
}
}
orderBoms.remove(indexOf);
// 生成表格标题行
String[] headers = { "成品货号", "料件货号", "内部版本号", "备案版本号", "ERP单耗", "有形损耗率", "无形损耗率", "保税比例", "申报单耗", "开始日期",
"结束日期", "备注" };
// -----设置导出表格-----
// 声明一个工作薄
HSSFWorkbook workbook = new HSSFWorkbook();
// 生成一个表格
HSSFSheet sheet = workbook.createSheet("企业成品耗用");
// 设置表格默认列宽度为15个字节
sheet.setDefaultColumnWidth(15);
sheet.autoSizeColumn(1, true);
// 生成一个样式
HSSFCellStyle style = workbook.createCellStyle();
// 设置这些样式
style.setAlignment(HSSFCellStyle.ALIGN_LEFT);
style.setVerticalAlignment(org.apache.poi.ss.usermodel.CellStyle.VERTICAL_CENTER);
style.setBorderBottom(HSSFCellStyle.BORDER_THIN);
style.setBorderLeft(HSSFCellStyle.BORDER_THIN);
style.setBorderRight(HSSFCellStyle.BORDER_THIN);
style.setBorderTop(HSSFCellStyle.BORDER_THIN);
style.setFillForegroundColor(IndexedColors.LEMON_CHIFFON.getIndex());
style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
// 生成一个字体
HSSFFont font = workbook.createFont();
font.setFontHeightInPoints((short) 12);
font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
// 把字体应用到当前的样式
style.setFont(font);
// 生成并设置另一个样式
HSSFCellStyle style2 = workbook.createCellStyle();
style2.setBorderBottom(HSSFCellStyle.BORDER_THIN);
style2.setBorderLeft(HSSFCellStyle.BORDER_THIN);
style2.setBorderRight(HSSFCellStyle.BORDER_THIN);
style2.setBorderTop(HSSFCellStyle.BORDER_THIN);
style2.setAlignment(HSSFCellStyle.ALIGN_LEFT);
style2.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
style2.setFillForegroundColor(IndexedColors.LEMON_CHIFFON.getIndex());
style2.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
// 生成另一个字体
HSSFFont font2 = workbook.createFont();
font2.setFontName("宋体");
font2.setBoldweight(HSSFFont.BOLDWEIGHT_NORMAL);
// 把字体应用到当前的样式
style2.setFont(font2);
// 产生表格标题行
HSSFRow row = sheet.createRow(0);
row.setHeightInPoints(30);
for (int x = 0; x < headers.length; x++) {
HSSFCell cell = row.createCell(x);
cell.setCellStyle(style);
HSSFRichTextString text = new HSSFRichTextString(headers[x]);
cell.setCellValue(text);
}
// 二维数组转树形
List<OrderBom> nodeList = new ArrayList<OrderBom>();
boolean mark;
for (OrderBom ob : orderBoms) {
mark = false;
for (OrderBom ob2 : orderBoms) {
if (ob.get_parentId() != null && ob.get_parentId().equals(ob2.getId())) {
mark = true;
if (ob2.getChildren() == null) {
ob2.setChildren(new ArrayList<OrderBom>());
ob2.getChildren().add(ob);
} else {
ob2.getChildren().add(ob);
}
}
}
if (!mark) {
nodeList.add(ob);
}
}
// 设置日期格式
SimpleDateFormat tf = new SimpleDateFormat("yyyy-MM-dd");
Integer lastRowNum = null;// 当前需要增加行的下标
String beginDate = null;
//将参数传进去后递归循环写入数据
judgeNull(nodeList, headers, sheet, style2, row, lastRowNum, beginDate, tf, product, billNo);
// 创建response输出流
SimpleDateFormat df = new SimpleDateFormat("yyMMdd-HH.mm");// 设置日期格式
String time = df.format(new Date());// new Date()为获取当前系统时间
OutputStream os = null;
try {
os = response.getOutputStream();
} catch (IOException e1) {
}
response.reset();
String filename = billNo + "." + time + ".xls";
response.setContentType("application/msexcel");
try {
response.setHeader("Content-disposition", "attachment; filename=" + URLEncoder.encode(filename, "UTF-8"));
workbook.write(os);
os.flush();
os.close();
} catch (Exception e) {
}
}
//写入数据并设置样式
private void judgeNull(List<OrderBom> orderBoms, String[] headers, HSSFSheet sheet, HSSFCellStyle style2,
HSSFRow row, Integer lastRowNum, String beginDate, SimpleDateFormat tf, List<OrderBom> product,
String billNo) {
for (OrderBom orderBom : orderBoms) {
List<OrderBom> children = orderBom.getChildren();
if (children != null) {
judgeNull(children, headers, sheet, style2, row, lastRowNum, beginDate, tf, product, billNo);
} else {
// 写入数据
lastRowNum = sheet.getLastRowNum() + 1;
row = sheet.createRow(lastRowNum);
row.setHeightInPoints(20);
row.createCell(0).setCellValue(product.get(0).getFnumber());
row.createCell(1).setCellValue(orderBom.getFnumber());
row.createCell(2).setCellValue(billNo);
row.createCell(3).setCellValue("");
row.createCell(4).setCellValue(orderBom.getFdosage());// ERP单耗
row.createCell(5).setCellValue(0);
row.createCell(6).setCellValue(0);
row.createCell(7).setCellValue(100);
row.createCell(8).setCellValue("");
beginDate = tf.format(orderBom.getBeginDate()); // 格式化日期
row.createCell(9).setCellValue(beginDate);
row.createCell(10).setCellValue("");
row.createCell(11).setCellValue("");
for (int j = 0; j < headers.length; j++) {
row.getCell(j).setCellStyle(style2);
}
}
}
}
先完成到这,初步涉略,讲的不是很细,后续有想法了再补充,欢迎各位指点~~