关于java导出Excel 并设置密码权限

时间:2024-05-18 21:48:05

最近工作不是特别忙,本来是想写一写高大尚点的技术分享,没想好,就随便分享点东西出来吧,第一次写技术分享,欢迎指正。

如果您正在苦苦寻找同时兼容 2003版 2007 版excel,

如果这是您要的效果:

关于java导出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 会响应给浏览器一个文件流,浏览器会自动下载这个文件