1.本导出excel方法需要poi-3.8-beta4.jar
2.本方法提供了导出至本地文件和导出至浏览器两种输出方法(如果要测导出浏览器,请注意传入HttpServletResponse 参数)。
3.本方法,将会导出.xsl文件,由于office限制excel存在65535行,所以,为了避免报错,为导出做出了限制,最多能导出内容65500行,加上标题和表头,最大容量为65503行数据。
4.关于列宽,由于poi自带的自适应不适合中文环境,并且,完全的自适应,如果遇到个别行的某一条数据特别长,也不符合人为观感。在此,对列宽做出了自定义的自适应。
列宽的自定义的自适应条件
1>如果内容的字段宽度小于标题的宽度,则启用标题的宽度,否则的话启用内容的宽度
2>设定最大宽度。如果excel中的某一列特别宽,比较影响美观,所以,设置了某行的某列宽度特别长,则忽略这条数据的长度(不影响该列其他行宽度对该列的影响)。所有列宽度不会超过设定的最大宽度。
3>为了效率考虑,内容字段宽度的判断,只取2000条做对比。
工具类:
//工具类
import java.util.ArrayList;
import java.util.List;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFPalette;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.hssf.util.Region;
public class ExcelUtil {
/**
* 导出Excel
*
* @param sheetName
* sheet名称
* @param title
* 表头
* @param head
* 标题
* @param values
* 内容
* @param wb
* HSSFWorkbook对象
* @return
*/
@SuppressWarnings("deprecation") // 60行使用了一个过期的方法,该标签使该类忽略标黄
public static HSSFWorkbook getHSSFWorkbook(String sheetName, String[] title, String head, String[][] values,
HSSFWorkbook wb) {
// 第一步,创建一个HSSFWorkbook,对应一个Excel文件
if (wb == null) {
wb = new HSSFWorkbook();
}
// 第二步,在workbook中添加一个sheet,对应Excel文件中的sheet
HSSFSheet sheet = wb.createSheet(sheetName);
// 标题
HSSFRow row_1 = sheet.createRow(0);
// 创建标题样式
HSSFCellStyle style_1 = wb.createCellStyle();
style_1.setAlignment(HSSFCellStyle.ALIGN_CENTER);// 居中
HSSFFont font_1 = wb.createFont();
font_1.setFontName("宋体");// 宋体加粗20
font_1.setFontHeightInPoints((short) 20);
font_1.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
style_1.setFont(font_1);
HSSFCell cell_1 = row_1.createCell(0);
cell_1.setCellStyle(style_1);
cell_1.setCellValue(head);
// 合并第一二行和与表头相同长度的列
Region region1 = new Region(0, (short) 0, 1, (short) (title.length - 1));
// 参数1:行号 参数2:起始列号 参数3:行号 参数4:终止列号
sheet.addMergedRegion(region1);
// 表头
// 第三步,在sheet中添加表头第2行,注意老版本poi对Excel的行数列数有限制 (最多65535行)
HSSFRow row = sheet.createRow(2);
// 第四步,创建单元格,并设置值表头 设置表头居中
HSSFCellStyle style_2 = wb.createCellStyle();
// 如果不使用POI提供的默认颜色,就需要自定颜色索引:
style_2.setFillForegroundColor(HSSFColor.LIME.index);
style_2.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
HSSFPalette palette = wb.getCustomPalette();// 拿到palette颜色板
palette.setColorAtIndex(HSSFColor.LIME.index, (byte) 68, (byte) 114, (byte) 196);
style_2.setAlignment(HSSFCellStyle.ALIGN_CENTER); // 创建一个居中格式
// 设置字体
HSSFFont font_2 = wb.createFont();
font_2.setFontName("宋体");// 宋体加粗20
font_2.setFontHeightInPoints((short) 12);
font_2.setColor(HSSFColor.WHITE.index);// 设置字体颜色
style_2.setFont(font_2);
// 声明列对象
HSSFCell cell_2 = null;
// 标题每一列的列宽
List<Integer> titleWidthList = new ArrayList<Integer>();
// 创建标题+设置列宽
for (int i = 0; i < title.length; i++) {
// 创建标题
cell_2 = row.createCell(i);
cell_2.setCellValue(title[i]);
cell_2.setCellStyle(style_2);
titleWidthList.add(title[i].getBytes().length * 2 * 256);
}
// 内容样式
HSSFCellStyle style_3 = wb.createCellStyle();
// 设置字体
HSSFFont font_3 = wb.createFont();
font_3.setFontName("宋体");//
font_3.setFontHeightInPoints((short) 12);
style_3.setFont(font_3);
// 创建内容
// 最大列宽
int maxWidth = 30 * 256;
// 最大的行号
int maxValueLen = (values.length < 65535 ? values.length : 65500);
for (int i = 0; i < maxValueLen; i++) {
row = sheet.createRow(i + 3);
// 第j列
for (int j = 0; j < values[i].length; j++) {
HSSFCell cell_3 = row.createCell(j);
cell_3.setCellStyle(style_3);
// 将内容按顺序赋给对应的列对象
cell_3.setCellValue(values[i][j]);
// 调整列宽
// sheet.setColumnWidth(j, maxWidth);
if (i < 2000) {
// 获取该列内容的宽度
int valueWidth = values[i][j].getBytes().length * 2 * 256;
// 获取该列标题的宽度
int titleWidth = titleWidthList.get(j);
// 设置该列的宽度
int width = maxWidth > (titleWidth > valueWidth ? titleWidth : valueWidth)
? (titleWidth > valueWidth ? titleWidth : valueWidth) : maxWidth;
// 向列设置宽度
sheet.setColumnWidth(j, width);
}
}
}
return wb;
}
}
测试类(后端):
//测试
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.springframework.stereotype.Service;
import com.tk.cy.utils.ExcelUtil;
@Service
public class ReportFormController {
public void export(HttpServletRequest request, HttpServletResponse response) {
// String a = (String) request.getAttribute("a");
// String b = (String) request.getParameter("a");
// 获取数据
// List<PageData> list = reportService.bookList(page);
// excel标题
String[] title = { "名称", "性别", "年龄", "学校", "班ssssssssssssss级", "学校", "学校", "学校" };
// 设置表头
// excel文件名
String fileName = "学生信息表" + System.currentTimeMillis() + ".xls";
// sheet名
String sheetName = "学生信息表";
// int[][] arr = new int[row][];
String[][] content = new String[500000][];
for (int i = 0; i < 500000; i++) {
content[i] = new String[title.length];
content[i][0] = "a" + i;
content[i][1] = "b" + i;
content[i][2] = "c" + i;
content[i][3] = "d" + i;
content[i][4] = "456";
content[i][5] = "a" + i + "加沙拉酱;加的解散数据流 就";
content[i][6] = "b" + i + "sskkslsk";
if (i == 5) {
content[i][7] = "张三李四王二赵六你好我好大家好案件法律砍价啊加法多岁的发顺丰";
} else if (i == 6) {
content[i][7] = "sskkslsk";
} else {
content[i][7] = "b";
}
}
// }
String head = "打印量报表";
// 创建HSSFWorkbook
HSSFWorkbook wb = ExcelUtil.getHSSFWorkbook(sheetName, title, head, content, null);
// 写入文件夹
try (FileOutputStream out = new FileOutputStream("d:\\aabbcc.xls")) {
// out
wb.write(out);// 写出文件
} catch (Exception e1) {
e1.printStackTrace();
}
// 响应到客户端
try {
this.setResponseHeader(response, fileName);
OutputStream os = response.getOutputStream();
wb.write(os);
os.flush();
os.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
//计算效率
for (int i = 0; i < 20; i++) {
long exetime = System.currentTimeMillis();
new ReportFormController().export(null, null);
exetime = System.currentTimeMillis() - exetime;
System.out.println(exetime);
}
}
// 发送响应流方法
public void setResponseHeader(HttpServletResponse response, String fileName) {
try {
try {
fileName = new String(fileName.getBytes(), "ISO8859-1");
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
response.setContentType("application/octet-stream;charset=ISO8859-1");
response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
response.addHeader("Pargam", "no-cache");
response.addHeader("Cache-Control", "no-cache");
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
前端测试:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script src="jquery.min.js"></script>
<script type="text/javascript" >
function btn2()
{
alert(1);
window.location.href="http://localhost:8080/SSIG/oss/MStest?a=666";
}
</script>
</head>
<body>
<input type="button" id="btn" onclick="btn2()"value="导出Excel" />
</body>
</html>
前端测试Controller:
package com.tk.cy.controller.oss.form;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import com.tk.cy.common.IdMaker;
import com.tk.cy.service.oss.form.ReportFormController;
/**
*
*
* @author
*
*/
@Controller
@RequestMapping(value = "/oss")
public class MStestController {
@Autowired
protected ReportFormController reportFormController;
/**
*
* @param req
* @return
*/
@RequestMapping(value = "/MStest", method = { RequestMethod.POST, RequestMethod.GET })
@ResponseBody
public void MStest(HttpServletRequest req, HttpServletResponse res, HttpSession session) {
String msgId = IdMaker.GetMsgId("MStest");
this.reportFormController.export(req, res);
}
}
最后导出的excel的样子:
能力有限,水平不高,欢迎交流指导。