Java使用poi组件导出excel报表,能导出excel报表的还可以使用jxl组件,但jxl想对于poi功能有限,jxl应该不能载excel插入浮动层图片,poi能很好的实现输出excel各种功能,介绍poi导出excel功能实现案例,算比较常用的功能实现以及导出excel需要注意的地方。
这里使用的为3.17版本的poi
org.apache.poi
poi-ooxml
3.17
org.apache.poi
poi-ooxml-schemas
3.17
这里我们就不多BB了,直接上代码
所需util
package com.ecb.userCenter.common.util;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.ss.usermodel.*;
import javax.servlet.http.HttpServletResponse;
import java.io.OutputStream;
/**
* @author Zuo Ning
* @date 2019/7/24 16:24
* @des 导出excel模板
*/
@Slf4j
public class ExcelUtils {
public static void exportExcelUsers(HttpServletResponse response, String[] handers, String excleName) throws Exception {
try {
HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet("sheet1");
HSSFCellStyle style = disFont(wb);
HSSFRow rowFirst = sheet.createRow(0);
rowFirst.setHeight((short) 300);
// 设置列宽
for (int i = 0; i < handers.length; i++) {
sheet.setColumnWidth((short) i, (short) 8300);
}
for (int i = 0; i < handers.length; i++) {
HSSFCell cell = rowFirst.createCell(i);
cell.setCellStyle(style);
cell.setCellValue(handers[i]);
}
//写出文件(path为文件路径含文件名)
OutputStream output = response.getOutputStream();
response.reset();
response.setHeader("Content-disposition", "attachment; filename=" + excleName + ".xls");
response.setContentType("application/msexcel");
wb.write(output);
output.close();
} catch (Exception e) {
log.error(e.getMessage());
throw e;
}
}
/**
* 设置excel样式
*
* @param wb
* @return
*/
public static HSSFCellStyle disFont(HSSFWorkbook wb) {
HSSFCellStyle style = wb.createCellStyle();
style.setBorderBottom(BorderStyle.THIN);//下边框
style.setBorderLeft(BorderStyle.THIN);//左边框
style.setBorderRight(BorderStyle.THIN);//右边框
style.setBorderTop(BorderStyle.THIN); //上边框
style.setAlignment(HorizontalAlignment.CENTER);//水平居中
style.setVerticalAlignment(VerticalAlignment.CENTER);//垂直居中
style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
style.setFillForegroundColor(IndexedColors.WHITE.index);
HSSFFont font = wb.createFont();
// font.setFontName("华文行楷");//设置字体名称
font.setFontHeightInPoints((short) 10);//设置字号
font.setItalic(false);//设置是否为斜体
font.setBold(true);//设置是否加粗
style.setFont(font);
return style;
}
}
servie层
//service实现层
public void exportWhitelistTemplate(HttpServletResponse response) {
try {
String time = DateUtils.getDate4yyyymmddhhmmss();
String excelName = java.net.URLEncoder.encode("用户白名单模板-" + time, "UTF-8");
String[] handers = {"姓名", "手机号"};
// 1导入硬盘
ExcelUtils.exportExcelUsers(response, handers, excelName);
} catch (Exception e) {
log.error(e.getMessage());
Result.fail(ResultCode.EXCEPTION_OTHER.getCode(), "导出失败");
}
}
controller层
//controller层
@GetMapping("/exportWhitelistTemplate")
@ApiOperation("导出用户白名单模板")
@IgnoreToken
public Result exportWhitelistTemplate(HttpServletResponse response) {
userWhitelistService.exportWhitelistTemplate(response);
return null;
}
导出后样式
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-93DXCwwN-1578555718786)(http://39.105.146.77:5927/upload/2020/1/4-d8a0297ad0c349158d0f63119a12d3f7.png)]
这里可以根据自己需求更改handers从而完成自己的需求
这里是导出带数据的,并且可以根据需求做一些处理
@Override
public void redemptionPackageDownLoad(HttpServletResponse response, OilCardLedgerQueryParameters params) {
JSONObject result = new JSONObject();
try {
Example example = new Example(UserOilCardOrderJournal.class);
Example.Criteria criteria = example.createCriteria();
//1.1 用户账户筛选
boolean userAccount = StringUtils.isNotEmpty(params.getUserAccount());
if (userAccount) {
criteria.andEqualTo("userAccount", params.getUserAccount());
}
//1.2 根据时间段筛选 (前端传来startTime和endTime)
boolean startTime = StringUtils.isNotEmpty(params.getStartTime());
boolean endTime = StringUtils.isNotEmpty(params.getEndTime());
if (startTime && endTime) {
criteria.andBetween("subTime", params.getStartTime(), params.getEndTime());
}
//1.3 根据来源进行筛选 需要判空
if (params.getSource() != null) {
criteria.andEqualTo("source", params.getSource());
}
//1.4 根据订单编号进行筛选 需要判空
if (StringUtils.isNotEmpty(params.getOrderCode())) {
criteria.andEqualTo("orderCode", params.getOrderCode());
}
//1.5 根据网店编号进行筛选 需要判空
if (StringUtils.isNotEmpty(params.getShopCode())) {
criteria.andEqualTo("shopCode", params.getShopCode());
}
//1.6 根据应用名称或易捷网店名称进行筛选 需要判空
if (StringUtils.isNotEmpty(params.getAppName())) {
criteria.andEqualTo("appName", params.getAppName());
}
//1.7 排序,前端不传参数时默认按照createTime降序排序
if (params.getSortBy() == null) {
example.orderBy("subTime").desc();
} else {
example.setOrderByClause(params.getSortBy() + (params.getDesc() ? " DESC" : " ASC"));
}
List list = oilCardOrderJournalMapper.selectByExample(example);
List subList = null;
if (list.size() > REDEMPTION_PACKAGE_NUMBER) {
subList = list.subList(0, 1000);
} else {
subList = list;
}
String time = DateUtils.getDate4yyyymmddhhmmss();
String excelName = java.net.URLEncoder.encode("兑换包列表-" + time, "UTF-8");
String[] handers = {"序号", "用户账号", "充值日期", "充值类型", "充值金额", "订单金额", "订单编号", "网店编码", "网点名称"};
// 1导入硬盘
exportExcelToDisk(response, handers, subList, excelName);
} catch (Exception e) {
log.error(e.getMessage());
result.put("", "对不起,下载失败");
}
}
这里根据产品需求 进行设置
private void exportExcelToDisk(HttpServletResponse response, String[] handers, List list, String excleName) throws Exception {
try {
HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet("sheet1");
HSSFCellStyle style = ExcelUtils.disFont(wb);
HSSFRow rowFirst = sheet.createRow(0);
rowFirst.setHeight((short) 500);
// 设置列宽
for (int i = 0; i < handers.length; i++) {
sheet.setColumnWidth((short) i, (short) 5000);
}
for (int i = 0; i < handers.length; i++) {
HSSFCell cell = rowFirst.createCell(i);
cell.setCellStyle(style);
cell.setCellValue(handers[i]);
}
for (int i = 0; i < list.size(); i++) {
UserOilCardOrderJournal fr = list.get(i);
String source = "";
if (fr.getSource() == 0) {
source = "线上购物";
}
if (fr.getSource() == 1) {
source = "线下购物";
}
if (fr.getSource() == 2) {
source = "新人大礼包";
}
if (fr.getSource() == 3) {
source = "分享App";
}
if (fr.getSource() == 4) {
source = "分享商品";
}
if (fr.getSource() == 5) {
source = "分享订单";
}
if (fr.getSource() == 6) {
source = "金采订单";
}
if (fr.getSource() == 7) {
source = "零售加油(核销指定券后赠送)";
}
if (fr.getSource() == 8) {
source = "游戏奖励";
}
if (fr.getSource() == 9) {
source = "保险返利";
}
HSSFRow row = sheet.createRow(i + 1);
row.setHeight((short) 400);
row.createCell(0).setCellValue(i + 1);
if (fr.getUserAccount() != null) {
row.createCell(1).setCellValue(fr.getUserAccount());
}
if (fr.getSubTime() != null) {
row.createCell(2).setCellValue(DateUtils.formatDateTime(fr.getSubTime()));
}
if (fr.getSource() != null) {
row.createCell(3).setCellValue(source);
}
if (fr.getGiveMoney() != null) {
row.createCell(4).setCellValue(fr.getGiveMoney().toString());
}
if (fr.getOrderMoney() != null) {
row.createCell(5).setCellValue(fr.getOrderMoney().toString());
}
if (fr.getOrderCode() != null) {
row.createCell(6).setCellValue(fr.getOrderCode());
}
if (fr.getShopCode() != null) {
row.createCell(7).setCellValue(fr.getShopCode());
}
if (fr.getAppName() != null) {
row.createCell(8).setCellValue(fr.getAppName());
}
}
//写出文件(path为文件路径含文件名)
OutputStream output = response.getOutputStream();
response.reset();
response.setHeader("Content-disposition", "attachment; filename=" + excleName + ".xls");
response.setContentType("application/msexcel");
wb.write(output);
output.close();
} catch (Exception e) {
log.error(e.getMessage());
throw e;
}
}
controller层
@ApiOperation(value = "导出兑换包信息")
@GetMapping("/downLoad")
@IgnoreToken
public void downLoad(HttpServletResponse response,
@RequestParam(value = "userAccount", required = false) String userAccount,
@RequestParam(value = "startTime", required = false) String startTime,
@RequestParam(value = "endTime", required = false) String endTime,
@RequestParam(value = "source", required = false) Integer source,
@RequestParam(value = "orderCode", required = false) String orderCode,
@RequestParam(value = "shopCode", required = false) String shopCode,
@RequestParam(value = "appName", required = false) String appName) {
OilCardLedgerQueryParameters params = new OilCardLedgerQueryParameters(userAccount, startTime, endTime, source, orderCode, shopCode, appName);
oilCardExchangeService.redemptionPackageDownLoad(response, params);
}
导出效果图
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-t1Q6pKs1-1578555718787)(http://39.105.146.77:5927/upload/2020/1/1-6e16a93b0ac9421a879f985597ed7077.png)]
service层
@Override
public boolean importWhitelist(MultipartFile file) throws IOException {
ExcelReader reader = ExcelUtil.getReader(file.getInputStream(), 0);
// 跳过标题从第一行读取数据
List> readAllResult = reader.read(1);
for (List
过滤空的内容(可省略)
/**
* 过滤空的内容
*
* @param objects 每一行数据数据
* @author
*/
private void filterNullContent(List objects) {
// 0 是序号
String name = String.valueOf(objects.get(0));
String mobilePhone = String.valueOf(objects.get(1));
if (StringUtils.isEmpty(name)) {
throw new BusinessException("会员姓名不能为空");
}
if (StringUtils.isEmpty(mobilePhone)) {
throw new BusinessException("会员手机号不能为空");
}
}
需导入的数据
这里就用一个demo来模拟一下不规则excel的导入
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7W49FJR1-1578555718787)(http://39.105.146.77:5927/upload/2020/1/2-73a6f90ab5424666b7052344315c989d.png)]
在实际开发中碰到脑路清奇的产品,就会出现这种需求,这种不规则的excel,目前我的思路是将没有规律的每行读出来,根据下标索引去定位数据(缺点:模板格式必须严格按照规定,不然数据会出现异常)。思路比较笨,仅供参考。借鉴一下还是可以的,如有更好的方法,请不要吝啬,告知一下!
这里就用一个demo来模拟一下不规则excel的导入
** utill **
package com.usercenter.util;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
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.xssf.usermodel.XSSFWorkbook;
import org.springframework.web.multipart.MultipartFile;
public class POIUtils {
private final static String XLS = "xls";
private final static String XLSX = "xlsx";
public static List readExcel(MultipartFile formFile) throws IOException{
//检查文件
checkFile(formFile);
//获得工作簿对象
Workbook workbook = getWorkBook(formFile);
//创建返回对象,把每行中的值作为一个数组,所有的行作为一个集合返回
List list = new ArrayList<>();
if(null!=workbook){
for(int sheetNum = 0;sheetNum
public static void main(String[] args) throws IOException {
File productFile = new File("C:\\Users\\16601\\Desktop\\aa.xlsx");
FileInputStream inputStream = new FileInputStream(productFile);
MultipartFile excelFile = new MockMultipartFile("file", "C:\\Users\\16601\\Desktop\\" + productFile.getName(), "text/plain", IOUtils.toByteArray(inputStream));
List rowList = POIUtils.readExcel(excelFile);
SalesOrderVo salesOrderVo = new SalesOrderVo();
//基本信息第一行
String[] basicInformationOne = rowList.get(1);
salesOrderVo.setClienteleName(basicInformationOne[1]);
salesOrderVo.setClienteleCode(basicInformationOne[3]);
salesOrderVo.setReceiptUser(basicInformationOne[7]);
//基本信息第二行
String[] basicInformationTwo = rowList.get(2);
salesOrderVo.setBusinessType(basicInformationTwo[1]);
salesOrderVo.setSalesDepartment(basicInformationTwo[3]);
salesOrderVo.setSalesPersonnel(basicInformationTwo[7]);
//基本信息第三行
String[] basicInformationThree = rowList.get(3);
salesOrderVo.setDeliveryTime(SimpleDate(basicInformationThree[1]));
salesOrderVo.setDeliveryType(basicInformationThree[3]);
salesOrderVo.setOrderTime(SimpleDate(basicInformationThree[7]));
//产品列表
//产品列表倒数第二行
String[] productListTwo = rowList.get(rowList.size() - 7);
salesOrderVo.setOrdersTotalAmount(productListTwo[1]);
salesOrderVo.setOrdersTotalDiscount(productListTwo[3]);
salesOrderVo.setSquaresTotal(productListTwo[7]);
salesOrderVo.setNumberTotal(productListTwo[9]);
//产品列表倒数第一行
String[] productListOne = rowList.get(rowList.size() - 6);
salesOrderVo.setBusinessManager(productListOne[1]);
salesOrderVo.setPaymentType(productListOne[3]);
salesOrderVo.setTotalQuantity(productListOne[7]);
// 物流信息
// 物流信息第一行
String[] logisticsInformationOne = rowList.get(rowList.size() - 4);
salesOrderVo.setDeliveryTime(SimpleDate(logisticsInformationOne[1]));
salesOrderVo.setReceiptTime(SimpleDate(logisticsInformationOne[3]));
// 物流信息第二行
String[] logisticsInformationTwo = rowList.get(rowList.size() - 3);
salesOrderVo.setReceiptAddress(logisticsInformationTwo[1]);
salesOrderVo.setReceiptUser(logisticsInformationTwo[3]);
// 物流信息第三行
String[] logisticsInformationThree = rowList.get(rowList.size() - 2);
salesOrderVo.setReceiptPhone(logisticsInformationThree[1]);
salesOrderVo.setTransportInfo(logisticsInformationThree[3]);
//备注行
String[] logisticsInformationFour = rowList.get(rowList.size() - 1);
salesOrderVo.setRemark(logisticsInformationFour[1]);
ArrayList list = new ArrayList<>();
//动态获取规则数据
for (int i = 6; i < rowList.size() - 7; i++) {
OrderproduceVo orderproduceVo = new OrderproduceVo();
String[] product = rowList.get(i);
orderproduceVo.setOrderCode(product[0]);
orderproduceVo.setProductCode(product[1]);
orderproduceVo.setProductName(product[2]);
orderproduceVo.setProductUnit(product[3]);
orderproduceVo.setProductNum(Integer.parseInt(product[4]));
orderproduceVo.setPrice(product[5]);
orderproduceVo.setDiscount(product[6]);
orderproduceVo.setAmount(product[7]);
orderproduceVo.setNumber(product[8]);
orderproduceVo.setSquareNumber(product[9]);
orderproduceVo.setRemark(product[10]);
list.add(orderproduceVo);
}
salesOrderVo.setProduces(list);
JSONObject result = JSONObject.parseObject(JSON.toJSONString(salesOrderVo));
System.out.println(result);
}
/**
* 格式化导入时间
*
* @param s
* @return
*/
private static String SimpleDate(String s) {
Date StartDate = HSSFDateUtil.getJavaDate(Double.valueOf(s));
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String format = sdf.format(StartDate);
return format;
}
}
输出结果
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LcMAVYLM-1578555718787)(http://39.105.146.77:5927/upload/2020/1/3-924bef1a9f6e419d8c3cc2de7e34d469.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pSh3WImN-1578555718788)(http://39.105.146.77:5927/upload/2020/1/4-512dfd9ac5e141e0bd9249ccc29d56d2.png)]
格式化导入时间是用来解决java读取之后把时间转为了距离1990年1月1号的天数,比如excel中时间为2018/9/16 18:30,java读取之后变成43359.77083就会有问题。
到这里全套的导入导出就完成了,供各位参考…