簡體   English   中英

我想使用Apache POI創建一個受密碼保護的Excel文件,然后將其下載到Servlet.getOutputStream()

[英]I want to Create a password protected excel file using Apache POI, and then give to for download to Servlet.getOutputStream()

我無權將文件保存到文件系統。 我在網上可以找到的所有示例都在使用文件系統。

我想在內存中創建工作簿,如下所示:

HSSFWorkbook workbook = new HSSFWorkbook();

將數據寫入工作簿...保護工作簿密碼。

然后將工作簿寫入輸出流,如下所示:

workbook.write(servlet.getOutputStream());

我能夠獲得以下與HttpServlet和HSSFWorkbook .xls文件一起使用的內容-WorkbookServlet.java:

package com.joshden;

import java.io.IOException;
import java.io.OutputStream;

import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.poi.hssf.record.crypto.Biff8EncryptionKey;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Workbook;

@WebServlet("/workbook")
public class WorkbookServlet extends HttpServlet {
    private static final long serialVersionUID = 4087954595439224462L;
    private static final String password = "foobar1";

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
        response.setContentType("application/vnd.ms-excel");
        response.addHeader("Content-Disposition", "attachment; filename=password_protected.xls");
        createAndWriteEncryptedWorkbook(response.getOutputStream());
    }

    private void createAndWriteEncryptedWorkbook(OutputStream requestOutputStream) throws IOException {
        HSSFWorkbook workbook = new HSSFWorkbook();
        populateWorkbook(workbook);
        Biff8EncryptionKey.setCurrentUserPassword(password);
        workbook.write(requestOutputStream);
        workbook.close();
    }

    private void populateWorkbook(Workbook workbook) {
        workbook.createSheet("TestSheet");
        // TODO create other sheets, populate cell values
    }

}

通過對/ workbook的請求,該servlet在內存中使用名為TestSheet的工作表創建HSSF工作簿。 密碼設置為“ foobar1”。 它提示瀏覽器將其下載為名稱為password_protected.xls的文件。

另請參閱Apache POI-加密支持 從Apache POI 3.16開始,僅對二進制格式(HSSF)進行了加密。 在撰寫本文時,還沒有發布3.16,並且在我的示例中使用了3.16-beta1。

encyprtion支持指南還包含有關創建加密(受密碼保護).xlsx(XSSF)文件的信息。 這是我創建的示例,該示例將提示文件名為password_protected.xlsx:

package com.joshden;

import java.io.IOException;
import java.io.OutputStream;
import java.security.GeneralSecurityException;

import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
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.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

@WebServlet("/workbook")
public class WorkbookServlet extends HttpServlet {
    private static final long serialVersionUID = 4087954595439224462L;
    private static final String password = "foobar1";

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.addHeader("Content-Disposition", "attachment; filename=password_protected.xlsx");
        createAndWriteEncryptedWorkbook(response.getOutputStream());
    }

    private void createAndWriteEncryptedWorkbook(OutputStream requestOutputStream) throws IOException {
        XSSFWorkbook workbook = new XSSFWorkbook();
        OPCPackage opc = workbook.getPackage();
        populateWorkbook(workbook);

        try {
            POIFSFileSystem fileSystem = new POIFSFileSystem();
            opc.save(getEncryptingOutputStream(fileSystem, password));
            fileSystem.writeFilesystem(requestOutputStream);
        }
        finally {
            workbook.close();
        }
    }

    private void populateWorkbook(Workbook workbook) {
        workbook.createSheet("TestSheet");
        // TODO create other sheets, populate cell values
    }

    private OutputStream getEncryptingOutputStream(POIFSFileSystem fileSystem, String password) throws IOException {
        EncryptionInfo encryptionInfo = new EncryptionInfo(EncryptionMode.agile);
        Encryptor encryptor = encryptionInfo.getEncryptor();
        encryptor.confirmPassword(password);

        try {
            return encryptor.getDataStream(fileSystem);
        } 
        catch (GeneralSecurityException e) {
            // TODO handle this better
            throw new RuntimeException(e);
        }
    }

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM