最近工作不是特别忙,本来是想写一写高大尚点的技术分享,没想好,就随便分享点东西出来吧,第一次写技术分享,欢迎指正。
如果您正在苦苦寻找同时兼容 2003版 2007 版excel,
如果这是您要的效果:
好了直接上代码:
package com.util;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.poifs.crypt.EncryptionInfo;
import org.apache.poi.poifs.crypt.EncryptionMode;
import org.apache.poi.poifs.crypt.Encryptor;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFFont;
import org.apache.poi.xssf.usermodel.XSSFRichTextString;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
/**
* Excel导出工具类 兼容版
*
* @author 改进优化版
*/
public class ExportExcelUtil {
private static org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(ExportExcelUtil.class);
// 显示的导出表的标题
private String title;
// 导出表的列名
private String[] rowName;
private List<Object[]> dataList = new ArrayList<Object[]>();
// 构造方法,传入要导出的数据
public ExportExcelUtil(String title, String[] rowName, List<Object[]> dataList) {
this.dataList = dataList;
this.rowName = rowName;
this.title = title;
}
/*
* 导出数据
*/
public void export(HttpServletRequest request, HttpServletResponse response) throws Exception {
try {
XSSFWorkbook workbook = new XSSFWorkbook(); // 创建工作簿对象
XSSFSheet sheet = workbook.createSheet(title); // 创建工作表
XSSFCellStyle columnTopStyle = this.getColumnTopStyle(workbook); // 获取列头样式对象
XSSFCellStyle style = this.getStyle(workbook); // 单元格样式对象
// 定义所需列数
int columnNum = rowName.length;
XSSFRow rowRowName = sheet.createRow(0); // 在索引2的位置创建行(最顶端的行开始的第二行)
rowRowName.setHeightInPoints(25); // 将列头设置默认行高
// 将列头设置到sheet的单元格中
for (int n = 0; n < columnNum; n++) {
XSSFCell cellRowName = rowRowName.createCell(n); // 创建列头对应个数的单元格
cellRowName.setCellType(XSSFCell.CELL_TYPE_STRING); // 设置列头单元格的数据类型
XSSFRichTextString text = new XSSFRichTextString(rowName[n]);
cellRowName.setCellValue(text); // 设置列头单元格的值
cellRowName.setCellStyle(columnTopStyle); // 设置列头单元格样式
}
// 将查询出的数据设置到sheet对应的单元格中
for (int i = 0; i < dataList.size(); i++) {
Object[] obj = dataList.get(i);// 遍历每个对象
XSSFRow row = sheet.createRow(i + 1);// 创建所需的行数
row.setHeightInPoints(20); // 将创建出的行设置默认行高
for (int j = 0; j < obj.length; j++) {
XSSFCell cell = null; // 设置单元格的数据类型
cell = row.createCell(j, XSSFCell.CELL_TYPE_STRING);
if (!"".equals(obj[j]) && obj[j] != null) {
cell.setCellValue(obj[j].toString()); // 设置单元格的值
}
cell.setCellStyle(style); // 设置单元格样式
}
}
// 让列宽随着导出的列长自动适应
for (int colNum = 0; colNum < columnNum; colNum++) {
int columnWidth = sheet.getColumnWidth(colNum) / 256;
for (int rowNum = 0; rowNum < sheet.getLastRowNum(); rowNum++) {
XSSFRow currentRow;
// 当前行未被使用过
if (sheet.getRow(rowNum) == null) {
currentRow = sheet.createRow(rowNum);
} else {
currentRow = sheet.getRow(rowNum);
}
if (currentRow.getCell(colNum) != null) {
XSSFCell currentCell = currentRow.getCell(colNum);
if (currentCell.getCellType() == XSSFCell.CELL_TYPE_STRING) {
int length = currentCell.getStringCellValue().getBytes().length;
if (columnWidth < length) {
columnWidth = length;
}
}
}
}
if (colNum == 0) {
sheet.setColumnWidth(colNum, (columnWidth - 2) * 256);
} else {
sheet.setColumnWidth(colNum, (columnWidth + 4) * 256);
}
}
if (workbook != null) {
ByteArrayOutputStream bout = null;
ByteArrayInputStream workbookinput = null;
OutputStream outstream = null;
OPCPackage opc = null;
OutputStream os = null;
try {
// 把工作薄输出到字节里面
bout = new ByteArrayOutputStream();
workbook.write(bout);
bout.flush();
workbookinput = new ByteArrayInputStream(bout.toByteArray());
// 读取临时文件进行加密
POIFSFileSystem fs = new POIFSFileSystem();
EncryptionInfo info = new EncryptionInfo(fs, EncryptionMode.agile);
Encryptor enc = info.getEncryptor();
enc.confirmPassword("123456");//打开excel 密码
// 然后把字节输入到输入流,然后输入到OPC包里面
opc = OPCPackage.open(workbookinput);
os = enc.getDataStream(fs);
opc.save(os);
opc.close();
// 返回给浏览器
outstream = response.getOutputStream();
response.reset();
response.setHeader("Content-disposition",
"attachment; filename=" + new String(title.getBytes(), "UTF-8") + ".xlsx");
response.setContentType("application/x-download");
fs.writeFilesystem(outstream);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (workbook != null) {
workbook.close();
}
if (bout != null) {
bout.close();
}
if (workbookinput != null) {
workbookinput.close();
}
if (outstream != null) {
outstream.close();
}
if (opc != null) {
opc.close();
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
/*
* 设置标题样式
*/
public XSSFCellStyle getTitleTopStyle(XSSFWorkbook workbook) {
// 设置字体
XSSFFont font = workbook.createFont();
// 设置字体大小
font.setFontHeightInPoints((short) 24);
// 字体加粗
font.setBoldweight(XSSFFont.BOLDWEIGHT_BOLD);
// 设置字体名字
font.setFontName("宋体");
// 设置样式;
XSSFCellStyle style = workbook.createCellStyle();
// 设置底边框;
style.setBorderBottom(XSSFCellStyle.BORDER_THIN);
// 设置底边框颜色;
style.setBottomBorderColor(IndexedColors.BLACK.getIndex());
// 设置左边框;
style.setBorderLeft(XSSFCellStyle.BORDER_THIN);
// 设置左边框颜色;
style.setLeftBorderColor(IndexedColors.BLACK.getIndex());
// 设置右边框;
style.setBorderRight(XSSFCellStyle.BORDER_THIN);
// 设置右边框颜色;
style.setRightBorderColor(IndexedColors.BLACK.getIndex());
// 设置顶边框;
style.setBorderTop(XSSFCellStyle.BORDER_THIN);
// 设置顶边框颜色;
style.setTopBorderColor(IndexedColors.BLACK.getIndex());
// 在样式用应用设置的字体;
style.setFont(font);
// 设置自动换行;
style.setWrapText(false);
// 设置水平对齐的样式为居中对齐;
style.setAlignment(XSSFCellStyle.ALIGN_CENTER);
// 设置垂直对齐的样式为居中对齐;
style.setVerticalAlignment(XSSFCellStyle.VERTICAL_CENTER);
return style;
}
/*
* 列头单元格样式
*/
public XSSFCellStyle getColumnTopStyle(XSSFWorkbook workbook) {
// 设置字体
XSSFFont font = workbook.createFont();
// 设置字体大小
font.setFontHeightInPoints((short) 11);
// 字体加粗
font.setBoldweight(XSSFFont.BOLDWEIGHT_BOLD);
// 设置字体名字
font.setFontName("宋体");
// 设置样式;
XSSFCellStyle style = workbook.createCellStyle();
// 设置底边框;
style.setBorderBottom(XSSFCellStyle.BORDER_THIN);
// 设置底边框颜色;
style.setBottomBorderColor(IndexedColors.BLACK.getIndex());
// 设置左边框;
style.setBorderLeft(XSSFCellStyle.BORDER_THIN);
// 设置左边框颜色;
style.setLeftBorderColor(IndexedColors.BLACK.getIndex());
// 设置右边框;
style.setBorderRight(XSSFCellStyle.BORDER_THIN);
// 设置右边框颜色;
style.setRightBorderColor(IndexedColors.BLACK.getIndex());
// 设置顶边框;
style.setBorderTop(XSSFCellStyle.BORDER_THIN);
// 设置顶边框颜色;
style.setTopBorderColor(IndexedColors.BLACK.getIndex());
// 在样式用应用设置的字体;
style.setFont(font);
// 设置自动换行;
style.setWrapText(false);
// 设置水平对齐的样式为居中对齐;
style.setAlignment(XSSFCellStyle.ALIGN_CENTER);
// 设置垂直对齐的样式为居中对齐;
style.setVerticalAlignment(XSSFCellStyle.VERTICAL_CENTER);
return style;
}
/*
* 列数据信息单元格样式
*/
public XSSFCellStyle getStyle(XSSFWorkbook workbook) {
// 设置字体
XSSFFont font = workbook.createFont();
// 设置字体大小
// font.setFontHeightInPoints((short)10);
// 字体加粗
// font.setBoldweight(XSSFFont.BOLDWEIGHT_BOLD);
// 设置字体名字
font.setFontName("宋体");
// 设置样式;
XSSFCellStyle style = workbook.createCellStyle();
// 设置底边框;
style.setBorderBottom(XSSFCellStyle.BORDER_THIN);
// 设置底边框颜色;
style.setBottomBorderColor(IndexedColors.BLACK.getIndex());
// 设置左边框;
style.setBorderLeft(XSSFCellStyle.BORDER_THIN);
// 设置左边框颜色;
style.setLeftBorderColor(IndexedColors.BLACK.getIndex());
// 设置右边框;
style.setBorderRight(XSSFCellStyle.BORDER_THIN);
// 设置右边框颜色;
style.setRightBorderColor(IndexedColors.BLACK.getIndex());
// 设置顶边框;
style.setBorderTop(XSSFCellStyle.BORDER_THIN);
// 设置顶边框颜色;
style.setTopBorderColor(IndexedColors.BLACK.getIndex());
// 在样式用应用设置的字体;
style.setFont(font);
// 设置自动换行;
style.setWrapText(false);
// 设置水平对齐的样式为居中对齐;
// style.setAlignment(XSSFCellStyle.ALIGN_CENTER);
// 设置垂直对齐的样式为居中对齐;
// style.setVerticalAlignment(XSSFCellStyle.VERTICAL_CENTER);
return style;
}
/*
* 实现方法
*/
public static void main(String[] args) throws Exception {
String title = "测试";
String[] rowsName = new String[] { "序号", "列头1", "列头2", "列头3", "列头4", "列头5" };
List<Object[]> dataList = new ArrayList<Object[]>();
Object[] objs = null;
for (int i = 0; i < 10; i++) {
objs = new Object[rowsName.length];
objs[0] = i;
objs[1] = "测试1";
objs[2] = "测试2";
objs[3] = "测试3";
objs[4] = "测试4";
objs[5] = "测试5";
dataList.add(objs);
}
ExportExcelUtil ex = new ExportExcelUtil(title, rowsName, dataList);
ex.export(request,response);
}
}
大家注意main是无法执行的:因为这里并没有 request,response 两个对象,这个demo 主要是方便理解,大家将main内的代码写在您项目Controller内,然后用前端js window.location.href='您的Controller';
即可看到效果,response 会响应给浏览器一个文件流,浏览器会自动下载这个文件