Apache POI是Apache提供给java来实现对office文件的读写的一套api
讲导出之前,首先把Apache POI的api地址贴一下,点击这里查看
jar包可以从apache poi官网下载
框架 struts+hibernate
这边不提供真实数据,
首先要定义以下四个参数,和他们的get,set方法
// 导出的文件的输出流
private InputStream zipFile;
// 文件的下载名
private String zipFileName;
// 页面判断excelzip是否成功
private static boolean state;
private static final String REGISTER_EXPORT_NAME="申请单查询结果";
public InputStream getZipFile() {
return zipFile;
}
public void setZipFile(InputStream zipFile) {
this.zipFile = zipFile;
}
public String getZipFileName() {
String fileName = REGISTER_EXPORT_NAME+"导出.zip";
try {
this.zipFileName = new String(fileName.getBytes(), "ISO8859-1");
} catch (Exception e) {
}
return zipFileName;
}
public void setZipFileName(String zipFileName) {
this.zipFileName = zipFileName;
}
public static boolean isState() {
return state;
}
public static void setState(boolean state) {
RegisterSearchAction.state = state;
}
因为打包时间较长,前端页面有遮罩层来阻止用户进行其他操作,当操作完成,通过ajax请求后台,获得true结果,则遮罩层消失
/**
* 判断excel生成打包是否成功
*
* @return
*/
public String exportState() {
ActionContext ac = ActionContext.getContext();
HttpServletResponse response = (HttpServletResponse) ac.get(StrutsStatics.HTTP_RESPONSE);
response.setCharacterEncoding("utf-8");
Gson json = new Gson();
String result = json.toJson(state);
try {
response.getWriter().write(result);
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
导出采用流的形式导出
/**
* 导出Excel
*
* @return
* @throws Exception
*/
public String reportExport() throws Exception {
state = false;
init();
getZipFileName();
if(cond == null){
cond = new RegisterCondition();
}
Calendar calendar = new GregorianCalendar();
Date sDate = null;
Date eDate = null;
if(cond.getEndTime() != null){
Date end = cond.getEndTime();
calendar.setTime(end);
calendar.add(Calendar.SECOND, 86399);
end = calendar.getTime();
eDate = end;
}
if(cond.getStartTime() != null){
Date strat = cond.getStartTime();
calendar.setTime(strat);
calendar.add(Calendar.SECOND, -1);
strat = calendar.getTime();
sDate = strat;
}
if(model == null){
model = new PageModel<>();
}
LoginVO login = getLoginInSession();
File zip = new File(zipFileName);
List fileNames = regServ.toExcel(REGISTER_EXPORT_NAME, login, cond, sDate, eDate);
File file[] = new File[fileNames.size()];
for (int i = 0; i < fileNames.size(); i++) {
file[i] = new File(fileNames.get(i));
}
try {
createZip(file, zip);
} catch (IOException e) {
e.printStackTrace();
}
FileInputStream in;
ByteArrayOutputStream output = new ByteArrayOutputStream();
try {
in = new FileInputStream(zip);
byte[] buff = new byte[4096];
int len;
while ((len = in.read(buff)) > 0) {
output.write(buff, 0, len);
byte[] ba = output.toByteArray();
zipFile = new ByteArrayInputStream(ba);
}
in.close();
zip.delete();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
output.flush();
output.close();
SimpleDateFormat sdf = new SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss");
LogVO log = new LogVO(YesOrNo.YES, getLoginInSession(),LogType.WEB, REGISTER_EXPORT_NAME+"导出", login.getLoginName()+ sdf.format(new Date())+REGISTER_EXPORT_NAME+"导出");
BossLogServer.getInstance().log(log);
} catch (IOException e) {
e.printStackTrace();
}
}
state = true;
return "record_export";
}
因为导出数据较大,都在一个excel里面可能会导致报错,所以这边导出使用分表,同时打包的形式输出
/**
* 将文件压缩成zip
*
* @param srcfile
* @param zipFile
* @throws IOException
*/
public void createZip(File[] srcfile, File zipFile) throws IOException {
if (zipFile.exists()) {
// 根据抽象路径创建一个新的空文件
zipFile.createNewFile();
}
ZipOutputStream out = new ZipOutputStream(new FileOutputStream(zipFile));
for (int i = 0; i < srcfile.length; i++) {
File tempFile = srcfile[i];
FileInputStream in = new FileInputStream(tempFile);
// 创建子文件
out.putNextEntry(new ZipEntry(srcfile[i].getName()));
byte[] buff = new byte[1024];
int len;
while ((len = in.read(buff)) > 0) {
out.write(buff, 0, len);
}
out.closeEntry();
in.close();
tempFile.delete();
}
out.close();
}
因为生成速度较慢,这边生成excel采用多线程线程池导出的形式
/**
* 信息导出
* @throws Exception
*/
@Override
public List toExcel(String appName, LoginVO login, RegisterCondition cond, Date sartDate, Date endDate) throws Exception {
PageModel model = new PageModel();
model.setPageSize(10000);
model = query(cond, model, login, sartDate, endDate);
int pageNum = model.getTotalRecords() / model.getPageSize() + 1;
List fileNames = new ArrayList();
// 创建线程池
ExecutorService pool = Executors.newCachedThreadPool();
// 计数器
CountDownLatch doneSignal = new CountDownLatch(pageNum);
for (int i = 0; i < pageNum; i++) {
pool.submit(new ExcelRunnable(doneSignal, fileNames, i, appName, cond, model, login, sartDate, endDate));
}
// 等待线程执行
doneSignal.await();
pool.shutdown();
return fileNames;
}
/**
* 使row线程安全
* @param sheet
* @param rownum
* @return
*/
private static synchronized HSSFRow getRow(HSSFSheet sheet, int rownum) {
return sheet.createRow(rownum);
}
/**
* 生成excel线程
* @author tuchunwei
*
*/
private class ExcelRunnable implements Runnable {
private final CountDownLatch doneSignal;
private String appName;
private RegisterCondition cond;
private PageModel model;
private LoginVO login;
private Date sartDate;
private Date endDate;
private int i;
private List fileNames;
public ExcelRunnable(CountDownLatch doneSignal, List fileNames, int i, String appName, RegisterCondition cond,
PageModel model, LoginVO login, Date sartDate, Date endDate) {
this.i = i;
this.appName = appName;
this.cond = cond;
this.model = model;
this.login = login;
this.sartDate = sartDate;
this.endDate = endDate;
this.fileNames = fileNames;
this.doneSignal = doneSignal;
}
@Override
public void run() {
// 得到报表标题和sheet页标题
String title = appName + "导出";
String sheetName = appName + "导出";
String fileName = appName + "表" + (i + 1) + ".xls";
model.setPageNo(i + 1);
// 得到第二行的所有标题,及各属性
String headers[] = { "时间", "名称", "应用名称", "证书类型(机构/用户)", "有效期", "证书策略",
"收费策略", "业务类型", "状态", "证书序列号", "介质序列号" };
model = exportQuery(cond, model, login, sartDate, endDate);
HSSFWorkbook book = null;
try {
book = createExcel(model, cond, title, headers, sheetName);
} catch (ParseException e2) {
e2.printStackTrace();
}
FileOutputStream output = null;
try {
output = new FileOutputStream(fileName);
fileNames.add(fileName);
} catch (FileNotFoundException e1) {
e1.printStackTrace();
}
try {
book.write(output);
output.flush();
output.close();
} catch (IOException e) {
e.printStackTrace();
} finally {
// 线程计数-1
doneSignal.countDown();
}
}
}
/**
* excel
*/
public HSSFWorkbook createExcel(PageModel model, RegisterCondition cond, String title, String headers[], String sheetName) throws ParseException {
HSSFRow row;
HSSFCell cell;
// 创建工作簿对象
HSSFWorkbook hssfWorkBook = new HSSFWorkbook();
// 创建 sheet 页,页名称
HSSFSheet sheet = hssfWorkBook.createSheet();
hssfWorkBook.setSheetName(0, sheetName);
// 设置列宽
this.setSheetColumnWidth(sheet);
// 创建行 创建单元格,为单元格填充值,第一行为标题,合并单元格
row = getRow(sheet,0);
row.setHeightInPoints(40);
cell = row.createCell(0);
cell.setCellValue(title);
cell.setCellStyle(getTitleStyle(hssfWorkBook));
sheet.addMergedRegion(new CellRangeAddress(0, (short) 0, 0, (short)(headers.length-1)));
HSSFCellStyle filterStyle = getFilterStyle(hssfWorkBook);
row = getRow(sheet,1);
row.setHeightInPoints(25);
cell = row.createCell(0);
StringBuffer buffer = new StringBuffer();
buffer.append("时间:");
if(cond.getStartTime()!=null && cond.getEndTime()!=null){
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
buffer.append(sdf.format(cond.getStartTime()) + " 至 " + sdf.format(cond.getEndTime()));
} else if(cond.getStartTime()!=null && cond.getEndTime()==null){
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
buffer.append(sdf.format(cond.getStartTime()) + " 至 今");
} else if(cond.getStartTime()==null && cond.getEndTime()!=null){
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
buffer.append("截止到 "+sdf.format(cond.getStartTime()));
} else if(cond.getStartTime()==null && cond.getEndTime()==null){
buffer.append("所有");
}
buffer.append(" 应用:");
if(StringUtils.isNotBlank(cond.getAppId())){
TbApp app = getAppById(cond.getAppId());
buffer.append(app.getName());
}else{
buffer.append("所有");
}
buffer.append(" 证书策略:");
if(StringUtils.isNotBlank(cond.getCertPolicy())){
TbCertPolicy policy = getPolicyById(cond.getCertPolicy());
buffer.append(policy.getName());
}else{
buffer.append("所有");
}
buffer.append(" 收费策略:");
if(StringUtils.isNotBlank(cond.getFeeScale())){
TbAppFeeScale feeScale = getFeeScalesById(cond.getFeeScale());
buffer.append(feeScale.getFeeName());
}else{
buffer.append("所有");
}
cell.setCellValue(buffer.toString());
cell.setCellStyle(filterStyle);
sheet.addMergedRegion(new CellRangeAddress(1, (short) 1, 0, (short)(headers.length-1)));
HSSFCellStyle styleContext = getContextStyle(hssfWorkBook);
// 产生表格第二行: 属性行
row = getRow(sheet,2);
row.setHeightInPoints(18);
for (int i = 0; i < headers.length; i++) {
cell = row.createCell(i);
cell.setCellStyle(getHeaderStyle(hssfWorkBook));
cell.setCellValue(headers[i]);
}
for (int i = 0; i < model.getList().size(); i++) {
row = getRow(sheet,(short) (i + 3));
row.setHeightInPoints(18);
//更新时间
cell = row.createCell(0);
if (model.getList().get(i).getModifyTime()==null) {
cell.setCellValue("");
} else {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm");
cell.setCellValue(sdf.format(model.getList().get(i).getModifyTime()));
}
cell.setCellStyle(styleContext);
//证书名称
cell = row.createCell(1);
if (StringUtils.isBlank(model.getList().get(i).getSubscriberName())) {
cell.setCellValue("");
} else {
cell.setCellValue(model.getList().get(i).getSubscriberName());
}
cell.setCellStyle(styleContext);
//应用名称
cell = row.createCell(2);
if (StringUtils.isBlank(model.getList().get(i).getAppName())) {
cell.setCellValue("");
} else {
cell.setCellValue(model.getList().get(i).getAppName());
}
//证书类型(机构/用户)
cell = row.createCell(3);
if (model.getList().get(i).getCertType() == null) {
cell.setCellValue("");
} else {
cell.setCellValue(CertificateType.toEnum(model.getList().get(i).getCertType()).getDesc());
}
cell.setCellStyle(styleContext);
//有效期
cell = row.createCell(4);
String validity = getCertValidity(model.getList().get(i).getPolicyId(), model.getList().get(i).getFeeScaleId(), model.getList().get(i).getBizType());
if (StringUtils.isBlank(validity)) {
cell.setCellValue("");
} else {
cell.setCellValue(validity);
}
//证书策略
cell = row.createCell(5);
if (StringUtils.isBlank(model.getList().get(i).getPolicyId())) {
cell.setCellValue("");
} else {
TbCertPolicy policy = getPolicyById(model.getList().get(i).getPolicyId());
if(policy!=null){
cell.setCellValue(policy.getName());
}
}
//收费策略
cell = row.createCell(6);
if (StringUtils.isBlank(model.getList().get(i).getFeeScaleId())) {
cell.setCellValue("");
} else {
TbAppFeeScale feeScale = getFeeScalesById(model.getList().get(i).getFeeScaleId());
if(feeScale!=null){
cell.setCellValue(feeScale.getFeeName());
}
}
//业务类型
cell = row.createCell(7);
Integer bizType = model.getList().get(i).getBizType();
if (bizType == null) {
cell.setCellValue("");
} else {
cell.setCellValue(BizType.toEnum(bizType).getDesc());
}
//状态
cell = row.createCell(8);
Integer status = model.getList().get(i).getStatus();
if (bizType == null) {
cell.setCellValue("");
} else {
cell.setCellValue(RegisterStatusType.toEnum(status).getDesc());
}
//证书序列号
cell = row.createCell(9);
if (StringUtils.isBlank(model.getList().get(i).getCertSn())) {
cell.setCellValue("");
} else {
cell.setCellValue(model.getList().get(i).getCertSn());
}
//介质编号
cell = row.createCell(10);
if (StringUtils.isBlank(model.getList().get(i).getKeySn())) {
cell.setCellValue("");
} else {
System.out.println(model.getList().get(i).getKeySn());
cell.setCellValue(model.getList().get(i).getKeySn());
}
}
return hssfWorkBook;
}
excel配置
/**
* 设置列宽
* @param sheet
*/
public void setSheetColumnWidth(HSSFSheet sheet) {
sheet.setColumnWidth(0, 5000);
sheet.setColumnWidth(1, 8000);
sheet.setColumnWidth(2, 5000);
sheet.setColumnWidth(3, 5000);
sheet.setColumnWidth(4, 3000);
sheet.setColumnWidth(5, 8000);
sheet.setColumnWidth(6, 10000);
sheet.setColumnWidth(7, 3000);
sheet.setColumnWidth(8, 3000);
sheet.setColumnWidth(9, 5000);
sheet.setColumnWidth(10, 5000);
sheet.setColumnWidth(11, 2000);
sheet.setColumnWidth(12, 2000);
sheet.setColumnWidth(13, 2000);
sheet.setColumnWidth(14, 2000);
sheet.setColumnWidth(15, 2000);
sheet.setColumnWidth(16, 2000);
sheet.setColumnWidth(17, 2000);
sheet.setColumnWidth(18, 2000);
sheet.setColumnWidth(19, 2000);
sheet.setColumnWidth(20, 2000);
sheet.setColumnWidth(21, 2000);
sheet.setColumnWidth(22, 2000);
sheet.setColumnWidth(23, 2000);
}
/**
* 第二行样式
* @param workbook
* @return
*/
public HSSFCellStyle getHeaderStyle(HSSFWorkbook workbook) {
HSSFCellStyle style = workbook.createCellStyle();
// 设置这些样式
style.setBorderBottom(HSSFCellStyle.BORDER_MEDIUM);
style.setBorderLeft(HSSFCellStyle.BORDER_MEDIUM);
style.setBorderRight(HSSFCellStyle.BORDER_MEDIUM);
style.setBorderTop(HSSFCellStyle.BORDER_MEDIUM);
style.setAlignment(HSSFCellStyle.ALIGN_LEFT);
style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);// 垂直居中
// 边框颜色
style.setTopBorderColor(HSSFColor.VIOLET.index);
style.setBottomBorderColor(HSSFColor.VIOLET.index);
style.setLeftBorderColor(HSSFColor.VIOLET.index);
style.setRightBorderColor(HSSFColor.VIOLET.index);
return style;
}
/**
* 标题样式
* @param workbook
* @return
*/
public HSSFCellStyle getTitleStyle(HSSFWorkbook workbook) {
HSSFCellStyle style = workbook.createCellStyle();
style.setAlignment(HSSFCellStyle.ALIGN_CENTER); // 字体居中
style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);// 垂直居中
HSSFFont font = workbook.createFont();
font.setFontName("宋体");
font.setFontHeightInPoints((short) 16);
font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);// 加粗
style.setFont(font);
return style;
}
/**
* 正文样式
* @param workbook
* @return
*/
public HSSFCellStyle getContextStyle(HSSFWorkbook workbook) {
HSSFCellStyle style = workbook.createCellStyle();
style.setAlignment(HSSFCellStyle.ALIGN_LEFT);
style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);// 垂直居中
return style;
}
/**
* 筛选条件样式
* @param workbook
* @return
*/
public HSSFCellStyle getFilterStyle(HSSFWorkbook workbook) {
HSSFCellStyle style = workbook.createCellStyle();
style.setAlignment(HSSFCellStyle.ALIGN_CENTER); // 字体居中
style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);// 垂直居中
HSSFFont font = workbook.createFont();
font.setFontName("宋体");
font.setFontHeightInPoints((short) 12);
style.setFont(font);
return style;
}
@Override
public PageModel exportQuery(RegisterCondition cond,
PageModel model, LoginVO login, Date sartDate, Date endDate) {
Session session = BossSessionFactory.getSession();
Transaction t = session.beginTransaction();
try {
IAppDao appDao = new AppDao(session);
List apps = appDao.getApps(login);
if (apps != null && apps.size() > 0) {
IRegisterDao regDao = new RegisterDao(session);
model = regDao.query(cond, model, apps, sartDate, endDate);
} else {
model.setList(null);
}
t.commit();
} finally {
session.close();
}
return model;
}
dao层这边不提供代码,自己把数据封装成一个PageModel,以类似分页的形式,分表
package zjca.common.web;
import java.util.ArrayList;
import java.util.List;
import zjca.common.config.CommonReadOnlyConfig;
public class PageModel {
/*
* 显示的页数
* 分页显示格式: 1 ... 3 4 5 6 7 ...9
* */
private static final int PAGES = 5;
public PageModel(){
this(CommonReadOnlyConfig.getInstance().defaultPageSize);
// this(1);
}
public PageModel(int pageSize){
this.totalRecords = 0;
this.pageSize = pageSize;
this.pageNo = 1;
}
// 结果集
private List list;
// 查询记录数
private int totalRecords;
// 每页多少条数据
private int pageSize;
// 第几页
private int pageNo;
//排序列名
private String orderColumn;
//是否顺序排列
private boolean isAsc;
/**
* 总页数
*
* @return
*/
public int getTotalPages() {
return (totalRecords + pageSize - 1) / pageSize;
}
/**
* 取得首页
*
* @return
*/
public int getTopPageNo() {
return 1;
}
public List getList() {
return list;
}
public void setList(List list) {
this.list = list;
}
public int getTotalRecords() {
return totalRecords;
}
public void setTotalRecords(int totalRecords) {
this.totalRecords = totalRecords;
}
public int getPageSize() {
return pageSize;
}
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
public int getPageNo() {
return pageNo;
}
public void setPageNo(int pageNo) {
this.pageNo = pageNo;
}
public int getFirstResult(){
return (pageNo - 1) * pageSize;
}
/**
* 获取分页
* */
public List getPages(){
List list = new ArrayList<>();
int totalPage = getTotalPages();
if(totalPage < PAGES){
for(int i = 1; i <= totalPage; i++){
list.add(i);
}
} else {
int range = PAGES / 2;
int tmp = pageNo - range ;
if(isShowFrontPoint()){
while(range > 0 ){
list.add(tmp);
tmp ++;
range --;
}
} else {
tmp = 1;
while(tmp < pageNo){
list.add(tmp);
tmp ++;
}
}
list.add(pageNo);
if(isShowEndPoint()){
range = PAGES / 2;
tmp = pageNo + 1;
while(range > 0){
list.add(tmp);
tmp ++;
range -- ;
}
} else {
tmp = pageNo + 1;
while(tmp <= totalPage){
list.add(tmp);
tmp ++;
}
}
}
return list;
}
public int getPrePage(){
int tmp = pageNo - 1;
if(tmp < getTopPageNo()){
tmp = getTopPageNo();
}
return tmp;
}
public int getNextPage(){
int tmp = pageNo + 1;
if(tmp > getTotalPages()){
tmp = getTotalPages();
}
return tmp;
}
/**
* 是否显示前面的省略号
* */
public boolean isShowFrontPoint(){
int range = PAGES / 2;
int totalPage = getTotalPages();
int tmp = pageNo - range - 1;
if(tmp > 0 && totalPage > 4){
return true;
} else {
return false;
}
}
/**
* 是否显示后端的省略号
* */
public boolean isShowEndPoint(){
int range = PAGES / 2;
int totalPage = getTotalPages();
int tmp = pageNo + range + 1 ;
if(totalPage <= tmp){
return false;
} else {
return true;
}
}
/**
* 当前页是否为首页
* */
public boolean isFirstPage(){
if(pageNo == getTopPageNo()){
return true;
} else {
return false;
}
}
public boolean isLastpage(){
if(pageNo == getTotalPages()){
return true;
} else {
return false;
}
}
public String getOrderColumn() {
return orderColumn;
}
public void setOrderColumn(String orderColumn) {
this.orderColumn = orderColumn;
}
public boolean isAsc() {
return isAsc;
}
public void setAsc(boolean isAsc) {
this.isAsc = isAsc;
}
}
struts文件配置
<action name="search/*" method="{1}" class="zjca.certificate.web.action.RegisterSearchAction">
<result name="reg_list">/WEB-INF/page/cert/reg_list.jspresult>
<result name="record_export" type="stream">
<param name="contentType">application/x-zip-compressedparam>
<param name="contentDisposition">attachment;filename="${zipFileName}"param>
<param name="bufferSize">4096param>
<param name="inputName">zipFileparam>
result>
action>
Jsp页面请求
function exportExport(target){
$.fn.jqLoading({ height: 100, width: 240, text: "正在加载中,请耐心等待...." });
$('.J_cert_app').css('border','2px solid #dadada');
$(target).css('border','2px solid #32a5e7');
/* document.getElementById("reportExport").action="cert/export/reportExport.htm";
document.getElementById("reportExport").submit(); */
var timer = setInterval(function getState(){
//判断是否生成excel成功
$.ajax({
url:"cert/ent/exportState.htm",
type:"POST",
data:"",
datatype:"String",
success:function (data){
if(data == "true"){
$.fn.jqLoading("destroy");
clearInterval(timer);
}
}
});
},100);
document.getElementById("search").action="cert/ent/reportExport.htm";
document.getElementById("search").submit();
}