java使用jxl生成excel表格,jsp使用js下载excel文件
后端代码
jxl版本为 jxl2.6.12
我自己是后端人员,所以这部分开发还算顺利,接下来全程记录下经验,有问题评论或者私信,随缘看到就回
maven jar包
<dependency>
<groupId>net.sourceforge.jexcelapi</groupId>
<artifactId>jxl</artifactId>
<version>2.6.12</version>
<scope>test</scope>
</dependency>
主体代码逻辑
引入的jar包
import jxl.Workbook;
import jxl.format.Alignment;
import jxl.format.Colour;
import jxl.format.UnderlineStyle;
import jxl.write.*;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.net.URLEncoder;
具体代码段
//jxl生成
String fileName = "文件名_" + new Date().getTime() + ".xls"; //定义文件名
ServletOutputStream outputStream = null;
WritableWorkbook workbook = null;
try {
// 定义title单元格样式:字体 下划线 斜体 粗体 颜色
WritableFont wf_title = new WritableFont(WritableFont.ARIAL, 30, WritableFont.NO_BOLD, false, UnderlineStyle.NO_UNDERLINE, Colour.BLACK);
WritableCellFormat wcf_title = new WritableCellFormat(wf_title);// 单元格定义
wcf_title.setBackground(Colour.GRAY_25); // 设置单元格的背景颜色
wcf_title.setAlignment(Alignment.CENTRE);// 设置对齐方式
wcf_title.setVerticalAlignment(VerticalAlignment.CENTRE);
wcf_title.setBorder(Border.ALL, BorderLineStyle.THIN, Colour.BLACK); //设置边框
wcf_title.setWrap(false); // 文字是否换行
wcf_title.setShrinkToFit(false); // 自适应列宽
//内容
WritableFont wf_table = new WritableFont(WritableFont.ARIAL, 15, WritableFont.NO_BOLD, false, UnderlineStyle.NO_UNDERLINE, Colour.BLACK);
WritableCellFormat wcf_table = new WritableCellFormat(wf_table);
wcf_table.setBackground(Colour.WHITE);
wcf_table.setAlignment(Alignment.CENTRE);
wcf_table.setVerticalAlignment(VerticalAlignment.CENTRE);
wcf_table.setBorder(Border.ALL, BorderLineStyle.THIN, Colour.BLACK);
wcf_table.setWrap(false);// 文字是否换行
wcf_table.setShrinkToFit(false);// 自适应列宽
outputStream = response.getOutputStream();
workbook = Workbook.createWorkbook(outputStream);
WritableSheet sheet = workbook.createSheet("sheet名称", 0);
sheet.mergeCells(0, 0, 10, 0);//合并单元格(左列,左行,右列,右行)
sheet.addCell(new Label(0, 0, "标题内容", wcf_title));//行,列,内容,样式
/**
* 表头
*/
HashMap<Integer, Integer> hashMap = new HashMap<Integer, Integer>();
String[] str = {"表头第一列", "表头第二列", "表头第三列", "表头第四列"};
for (int i = 0; i < str.length; i++) {
String msg = str[i];
int length = msg.length();
hashMap.put(i, length);
sheet.addCell(new Label(i, 1, msg, wcf_table)); // 内容
sheet.setColumnView(i, length * 5); //列宽
}
/**
* 表格中每行
*/
for (int i = 0; i < rfmPublicPushList.size(); i++) {
ArrayList<String> lines = toLines(rfmPublicPushList.get(i), i);
for (int i1 = 0; i1 < lines.size(); i1++) {
if (StringUtils.isBlank(lines.get(i1)) || PLACEHOLDER.equals(lines.get(i1))) {
//占位符则跳过
sheet.addCell(new Label(i1, i + 2, null, wcf_table));
continue;
}
String msg = lines.get(i1);
sheet.addCell(new Label(i1, i + 2, msg, wcf_table));
Integer columnView = hashMap.get(i1);
if (columnView == null || columnView < msg.length()) {
//本格数据长度大于之前的长度,则重新设置本列宽度
hashMap.put(i1, msg.length());
sheet.setColumnView(i1, msg.length() * 3); //列宽
}
}
}
//推流
response.setContentType("application/x-www-form-urlencoded;charset=UTF-8");
if (request.getHeader("User-Agent").toUpperCase().indexOf("MSIE") > 0) { //IE浏览器
fileName = URLEncoder.encode(fileName, "UTF-8");
} else {
fileName = new String(fileName.getBytes("UTF-8"), "ISO8859-1");
}
response.setHeader("Content-Disposition", "p_w_upload; filename=" + fileName);
outputStream.flush();
workbook.write();
} catch (Exception e) {
log.error("excel生成失败! " + e.getMessage(), e);
throw new RuntimeException("excel生成失败!");
} finally {
try {
workbook.close();
outputStream.close();
} catch (Exception e1) {
log.error("关闭流失败!" + e1.getMessage(), e1);
}
}
重点详解
表头和表格内容两种格式
// 定义title单元格样式:字体 下划线 斜体 粗体 颜色
WritableFont wf_title = new WritableFont(WritableFont.ARIAL, 30, WritableFont.NO_BOLD, false, UnderlineStyle.NO_UNDERLINE, Colour.BLACK);
WritableCellFormat wcf_title = new WritableCellFormat(wf_title);// 单元格定义
wcf_title.setBackground(Colour.GRAY_25); // 设置单元格的背景颜色
wcf_title.setAlignment(Alignment.CENTRE);// 设置对齐方式
wcf_title.setVerticalAlignment(VerticalAlignment.CENTRE);
wcf_title.setBorder(Border.ALL, BorderLineStyle.THIN, Colour.BLACK); //设置边框
wcf_title.setWrap(false); // 文字是否换行
wcf_title.setShrinkToFit(false); // 自适应列宽
//内容
WritableFont wf_table = new WritableFont(WritableFont.ARIAL, 15, WritableFont.NO_BOLD, false, UnderlineStyle.NO_UNDERLINE, Colour.BLACK);
WritableCellFormat wcf_table = new WritableCellFormat(wf_table);
wcf_table.setBackground(Colour.WHITE);
wcf_table.setAlignment(Alignment.CENTRE);
wcf_table.setVerticalAlignment(VerticalAlignment.CENTRE);
wcf_table.setBorder(Border.ALL, BorderLineStyle.THIN, Colour.BLACK);
wcf_table.setWrap(false); // 文字是否换行
wcf_table.setShrinkToFit(false); // 自适应列宽
直接将 HttpServletResponse 的输出流放进来
outputStream = response.getOutputStream();
workbook = Workbook.createWorkbook(outputStream);
设置表格内容重点是列宽
自动调整列宽的其它方法试了没多大用,这里就手动设置下
这里是表头,我直接用了和表格内容一样的样式,设置的列宽是参数长度的5倍
sheet.addCell(new Label(i, 1, msg, wcf_table)); // 内容
sheet.setColumnView(i, length * 5); //列宽
这里是表格内容,列宽还设置5倍就太长了,就设置了3倍
获取实体类,将其转换为list,然后遍历,参数为空则在list中存一个占位符,避免混乱
然后获取当前参数长度,如果大于之前最长的参数,则重新设置本列的列宽
/**
* 表格中每行
*/
for (int i = 0; i < rfmPublicPushList.size(); i++) {
ArrayList<String> lines = toLines(rfmPublicPushList.get(i), i);
for (int i1 = 0; i1 < lines.size(); i1++) {
if (StringUtils.isBlank(lines.get(i1)) || PLACEHOLDER.equals(lines.get(i1))) {
//占位符则跳过
sheet.addCell(new Label(i1, i + 2, null, wcf_table));
continue;
}
String msg = lines.get(i1);
sheet.addCell(new Label(i1, i + 2, msg, wcf_table));
Integer columnView = hashMap.get(i1);
if (columnView == null || columnView < msg.length()) {
//本格数据长度大于之前的长度,则重新设置本列宽度
hashMap.put(i1, msg.length());
sheet.setColumnView(i1, msg.length() * 3); //列宽
}
}
}
输出到前台
没啥好讲的
//推流
response.setContentType("application/x-www-form-urlencoded;charset=UTF-8");
if (request.getHeader("User-Agent").toUpperCase().indexOf("MSIE") > 0) { //IE浏览器
fileName = URLEncoder.encode(fileName, "UTF-8");
} else {
fileName = new String(fileName.getBytes("UTF-8"), "ISO8859-1");
}
response.setHeader("Content-Disposition", "p_w_upload; filename=" + fileName);
outputStream.flush();
workbook.write();
} catch (Exception e) {
log.error("excel生成失败! " + e.getMessage(), e);
throw new RuntimeException("excel生成失败!");
} finally {
try {
workbook.close();
outputStream.close();
} catch (Exception e1) {
log.error("关闭流失败!" + e1.getMessage(), e1);
}
}
前端代码
前端代码我用的很简单的请求方式,太复杂的我都试过,都不好用,也许是因为我不会前端,
jsp中按钮
<button id="toExcel" class="button_fss" style="width:45px;" onclick="toExcel()">导出</button>
js代码
就是一个简单的请求,没有做任何处理,因为我不是专业的前端,想试试复杂点的请自行查询吧,我试了两天都解析不了excel文件,找到了发发善心给我看看,不过搜索的前几页我都看过
function toExcel() {
window.location.href = "url";
}
style设置按钮样式
.button_fss {
height:23px;
border:#6280bf solid 1px;;
padding:2px 0px;
background-color:#718eca;
color:#FFF;
cursor:pointer;
width:60px;
}
.button_fss:hover {background-color: #718eca}
.button_fss:active {
background-color: #718eca;
box-shadow: 0 5px #666;
transform: translateY(4px);
}
完结撒花
对我来说难点就在前端代码,后端逻辑没啥大问题