目录
一、效果图
二、excle 生成的工具类原理
通过调用工具类,先判断在服务器中指定的文件夹中有没有存在同名的 excle 表,有的话就先删除掉,没有的话,就在指定的文件夹中生成一份新的 excle 表格,再调用浏览器的下载接口,把 excle 表下载到自己电脑上的指定位置,然后删除掉服务器上的 excle 表格。
三、excle 生成的工具类源码
CreateExcelFile : 生成 excle 的函数
send : 调用浏览器下载接口的函数
main : 测试类,可以自己运行下测试工具类是否能够正常使用。
源码中部分可能需要修改的地方,都带有解释,其它自己看。
需要导入的两个 jar 包:
package com.utils;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletResponse;
import jxl.Workbook;
import jxl.format.Alignment;
import jxl.format.Border;
import jxl.format.BorderLineStyle;
import jxl.format.Colour;
import jxl.format.UnderlineStyle;
import jxl.format.VerticalAlignment;
import jxl.write.Label;
import jxl.write.NumberFormats;
import jxl.write.WritableCellFormat;
import jxl.write.WritableFont;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;
import jxl.write.WriteException;
public class MakeExcel {
public MakeExcel() {}
// 入参是一个list,一条数据存一个map对象,map对象中存列和值得对应关系,destFile当然就是要存的文件信息。
// headList很重要,它是列的展示,当然和数据的列要对应不然找不到对应的地方存储。
public static void CreateExcelFile(List<Map<String, Object>> list, File destFile, List<String> headList,
String message) throws WriteException, IOException {
int sizeAll = list.size();
// 设置每页最大条数 65534 ,求出整数页 wholeNumber
int wholeNumber = sizeAll / 65534;
// 求出最后一页的条数
int yu = sizeAll % 65534;
int sheetSize = 1;
int flagList = 1;
if (sizeAll <= 65534) {
sheetSize = 1;
} else {
if (yu > 0) {
sheetSize = wholeNumber + 1;
} else {
sheetSize = wholeNumber;
}
}
WritableWorkbook book = null;
book = Workbook.createWorkbook(destFile);
if (list.size() == 0) {
book.write();
} else {
for (int j = 0; j < sheetSize; j++) {
int index;
System.out.println("*************************sheet(excle的左下角)" + j + "***************************");
WritableSheet sheet = book.createSheet(destFile.getName().replace(".xls", "") + j, j);
/**
* ARIAL : 字体样式 【WritableFont.createFont("宋体") : 宋体字体的设置】
* 19 : 字体大小
* WritableFont.BOLD, false 是判断是否为斜体,选择true时为斜体 ,默认为 false
*/
WritableFont BoldFont = new WritableFont(WritableFont.TIMES, 15);
WritableCellFormat wcf_center = new WritableCellFormat(BoldFont);
wcf_center.setBorder(Border.ALL, BorderLineStyle.THIN); // 线条
wcf_center.setVerticalAlignment(VerticalAlignment.CENTRE); // 文字垂直对齐
wcf_center.setAlignment(Alignment.CENTRE); // 文字水平对齐
wcf_center.setWrap(false); // 文字是否换行
// wcf_center.setBackground(Colour.LIGHT_GREEN);// 单元格背景颜色
for (int i = 0; i < headList.size() + 1; i++) {
sheet.setColumnView(i, 30);// 设置第i列的宽度
}
// 合并首行
sheet.mergeCells(0, 0, headList.size() - 1, 0);
sheet.addCell(new Label(0, 0, message, wcf_center));
index = 0;
for (String name : headList) {
sheet.addCell(new Label(index, 1, name, wcf_center));
index++;
}
int i = 0;
int t = 2;
while (flagList <= list.size()) {
index = 0;
if (i < 65534) {
for (String name : headList) {
sheet.addCell(new Label(index, t, list.get(flagList - 1).get(name) + "", wcf_center));
index++;
}
i++;
t++;
flagList++;
} else {
break;
}
}
}
}
book.write();
if (book != null)
book.close();
}
/**
* 文件下载
*
* @param filepath 文件路径
* @param response
*/
public static void send(String filepath, HttpServletResponse response) {
try {
File file = new File(filepath);// path是文件地址
String filename = file.getName();// 获取日志文件名称
InputStream fis = new BufferedInputStream(new FileInputStream(filepath));
byte[] buffer = new byte[fis.available()];
fis.read(buffer);
fis.close();
response.reset();
// 先去掉文件名称中的空格,然后转换编码格式为utf-8,保证不出现乱码,这个文件名称用于浏览器的下载框中自动显示的文件名
response.addHeader("Content-Disposition",
"attachment;filename=" + new String(filename.replaceAll(" ", "").getBytes("utf-8"), "iso8859-1"));
response.addHeader("Content-Length", "" + file.length());
OutputStream os = new BufferedOutputStream(response.getOutputStream());
response.setContentType("application/octet-stream");
os.write(buffer);// 输出文件
os.flush();
os.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
List<Map<String, Object>> list = new ArrayList<>();
for (int i = 0; i < 195534; i++) {
Map<String, Object> map = new HashMap<>();
map.put("a", "a" + i);
map.put("b", "b" + i);
map.put("c", "c" + i);
map.put("d", "d" + i);
list.add(map);
}
// 首行表头信息
List<String> ll = new ArrayList<>();
ll.add("a");
ll.add("b");
ll.add("c");
ll.add("d");
try {
CreateExcelFile(list, new File("d:/a.xls"), ll, "单据");
} catch (WriteException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
四、在 Controller 层中如何使用?
代码中有解释
/**
* 下载用户 excle 表接口
* @param response
* @throws IOException
*/
@RequestMapping("/download")
public void download(HttpServletResponse response) throws IOException {
//可以根据自己的实际情况指定一个地方存放 excle 文件,记得要文件的全名
String FILEPATH = "d:/a.xls";
// 判断 "d:/a.xls" 文件是否已经存在,如果存在就删除掉
deleteFile(FILEPATH);
// 首行表头信息
List<String> ll = new ArrayList<>();
ll.add("用户ID");
ll.add("用户账号");
ll.add("用户密码");
ll.add("今日状态");
ll.add("总签到次数");
// 获取所有用户信息
List<TUser> allUserList = userService.displayAllUser();
// 将用户的相关信息遍历到 List<Map<String, Object>> 中
List<Map<String, Object>> list = new ArrayList<>();
for (TUser tUser : allUserList) {
Map<String, Object> map = new HashMap<>();
map.put("用户ID", tUser.getUserid());
map.put("用户账号", tUser.getUsername());
map.put("用户密码", tUser.getPassword());
map.put("今日状态", tUser.getState());
map.put("总签到次数", tUser.getCount());
list.add(map);
}
try {
// 第一个参数:表格中的数据
// 第二个参数:表格保存的路径
// 第三个参数:表格第二行的列信息
// 第四个参数:表格第一行的表头信息
// 参照效果图看会清楚些
MakeExcel.CreateExcelFile(list, new File(FILEPATH), ll, "Tell me");
} catch (WriteException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
//调用浏览器下载接口
MakeExcel.send(FILEPATH, response);
boolean deleteFileState = deleteFile(FILEPATH);
if (deleteFileState) {
System.out.println("服务器上文件删除成功!!!");
} else {
System.out.println("服务器上文件删除失败!!!");
}
}
/**
* 删除单个文件
*
* @param sPath 被删除文件的文件名
* @return 单个文件删除成功返回true,否则返回false
*/
public boolean deleteFile(String sPath) {
boolean flag = false;
File file = new File(sPath);
// 路径为文件且不为空则进行删除
if (file.isFile() && file.exists()) {
file.delete();
flag = true;
}
return flag;
}
五、测试
先在 tomcat 下跑起来,然后直接调用。由于我这里没有写前端,就直接在浏览器上输入链接:http://localhost:8080/sign/download(这是我自己项目的链接,你根据自己的实际项目名称去改),在浏览器上运行之后,浏览器会弹出如下的下载窗口。剩下的就跟我们平时在浏览器上下载东西一样了。下载后的表格效果图在博客前面已经给了。如果不喜欢这样的表格,可以自行根据注释修改。