パスワード付きのExcelファイル作成ツール（JAVA）

# 概要
WEB上で処理結果をExcelファイルに保存したファイルにパスワードを設定するツール作成のメモです。

# 事前準備
以下の開発環境を用意します。

■開発環境及びライブラリ準備
・JDK最新バージョン：java version "20" 2023-03-21
https://download.oracle.com/java/20/latest/jdk-20_windows-x64_bin.exe

・ECLIPSE
https://mergedoc.osdn.jp/

・POIライブラリ
https://archive.apache.org/dist/poi/release/bin/
※必要なライブラリは以下のものです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/162336/73263220-92fa-0ba6-5243-cb8c18b14e41.png)


# ソースコード
以下のソースを作成します。

~~~java
package SetPasswordExcel;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import org.apache.poi.hssf.record.crypto.Biff8EncryptionKey;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.openxml4j.opc.PackageAccess;
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.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public class SetPassword {
    public static void main(String[] args) {
        try {
        	if(args.length!=3) {
        		System.out.println("引数を３つ指定してください。");
        		System.out.println("例） java -jar SetPassword.jar [inputfile] [outputfile] [password]");
        	}
        	
        	File inFile = new File(args[0]);
        	String infileName = inFile.getName();
        	String inext = infileName.substring(infileName.lastIndexOf(".") + 1);
        	
        	File outFile = new File(args[1]);
        	String outfileName = outFile.getName();
        	String outext = outfileName.substring(outfileName.lastIndexOf(".") + 1);
        	
        	if(inext.equals("xlsx")) {
        		try(POIFSFileSystem fs = new POIFSFileSystem()) {
        			EncryptionInfo info = new EncryptionInfo(EncryptionMode.agile);
        			Encryptor encryptor = info.getEncryptor();
        			
        			encryptor.confirmPassword(args[2]);
        			
        			try(OPCPackage opc = OPCPackage.open(inFile, PackageAccess.READ_WRITE);
        					OutputStream os = encryptor.getDataStream(fs)){
        				opc.save(os);
        			}
        			
        			try(FileOutputStream fos = new FileOutputStream(args[1])){
        				fs.writeFilesystem(fos);
        			}
        		}catch(IOException e) {
        			e.printStackTrace();
        		}
        		
        		System.out.println("Protected Excel(.xlsx) file has been created successfully.");
        	}
        	
        	if(inext.equals("xls")) {
        		try {
        			FileInputStream fi = null;
        			HSSFWorkbook wb = null;
        			
        			fi = new FileInputStream(args[0]);
        			Biff8EncryptionKey.setCurrentUserPassword(args[2]);
        			wb = new HSSFWorkbook(fi);
        			
        			wb.writeProtectWorkbook(args[2], "");
        			
        			wb.write(new FileOutputStream(args[1]));
        			
        			wb.close();
        		}catch(IOException e) {
        			e.printStackTrace();
        		}
        		
        		System.out.println("Protected Excel(.xls) file has been created successfully.");
        	}
        	
        }catch (Exception e) {
            e.printStackTrace();
        }
    }
}
~~~

■下記の画面でプロジェクト名およびメインクラスを指定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/162336/3d961b00-92bd-2be4-5fce-b39042727e38.png)

■依存関係のライブラリを確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/162336/6051509e-88da-dd1c-9edb-8f03d9c72e92.png)

# JARファイル作成
以下の手順でJARファイルを作成します。

①エクスポートメニューを押下
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/162336/7f933457-4a43-d65a-750e-a837ef5d5c83.png)

②実行可能JARファイルを選択と「次へ」ボタンを押下
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/162336/21a3a7e8-126d-e7d3-fe92-133ea32c54c3.png)

③起動構成を選択とエクスポート先を指定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/162336/2f04d65c-e5aa-54da-7c17-c9fcfc6d0a06.png)

④完了ボタンを押下
JARファイルが作成されます。
※起動構成及びメインクラスが正しく指定がされていない場合、JARファイルが正常に実行されないです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/162336/da35cb6a-b2a4-037d-40d3-365d85f10ce8.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/162336/5a5dd83a-bf61-bd9d-d1cd-636dc47889ea.png)

警告は表示されますが、一旦これで完了です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/162336/04efac41-2524-1b4b-8edf-44552daaab0f.png)

# JARファイル
以下のディレクトリを確認します。JARファイルが作成されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/162336/8b244e70-0d27-c834-e1ab-3f53ad7b020e.png)

# Excelファイルを作成
適当にExcelファイルにコメントを入れてファイルを保存します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/162336/eae2051e-f859-f742-9ca5-e047562596c3.png)

# JARファイルを実行
以下のコマンドをプロンプト画面で実行します。

■コマンド
java -jar SetPassword.jar 20230426.xlsx 20230426_pwd.xlsx Passw0rd

■正しく実行されない場合
~~~bash
C:\workspace>java -jar SetPassword.jar 20230426.xlsx 20230426_pwd.xlsx Passw0rd
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/logging/log4j/LogManager
        at org.apache.poi.poifs.filesystem.POIFSFileSystem.<clinit>(POIFSFileSystem.java:68)
        at SetPasswordExcel.SetPassword.main(SetPassword.java:35)
Caused by: java.lang.ClassNotFoundException: org.apache.logging.log4j.LogManager
        at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641)
        at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
        at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
        ... 2 more
~~~


①下記の画面で実行構成を押下
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/162336/8cf591e6-7c74-5eec-b752-b7b46f664580.png)

②新規構成を押下
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/162336/32f088c2-978c-c617-a725-a19dfdad7092.png)

③名前、プロジェクト、メインクラスを選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/162336/588f2072-bef2-2339-fa7e-6a0ccff97d51.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/162336/424f46d8-1bd5-b233-fdc9-140ff7df9baf.png)

④もう一度エクスポートメニューを押下して再度JARファイルを作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/162336/4d1f9e0b-1116-da90-003b-676aea6defc7.png)

■正しく実行された場合
~~~bash
C:\workspace>java -jar SetPassword.jar 20230426.xlsx 20230426_pwd.xlsx Passw0rd
Protected Excel(.xlsx) file has been created successfully.
~~~

■パスワード付きのファイルを確認
①下記のパスに作成されたファイルを開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/162336/f7a7ff23-b946-b7fe-de58-6ec2480d0a5c.png)

②次のようにパスワードを聞かれる画面が表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/162336/bb82bd9b-c2a1-b2d9-cfcc-e8b10c84f406.png)

③コマンドで指定したパスワードを指定しますと内容が正しく表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/162336/6811abdb-4bb7-cfac-a4ee-c26418832ce4.png)

# その他
今回のソースにはExcel2003ファイル形式もパスワード設定が可能です。
次のコマンドを実行してみたら正常にパスワード付きのファイルが作成されます。

~~~bash
C:\workspace>java -jar SetPassword.jar 20230426.xls 20230426_pwd.xls Passw0rd
Protected Excel(.xls) file has been created successfully.
~~~

# 終わりに
元々はPythonで実現してみたかったですが、その場合は、Windows環境じゃないとダメでしたので、Linux上でのことを考えてJAVAでパスワード付きのファイル作成はできないかと思ってネットのものを参考して作成ができました。
元々参照していたサイトのメモができなかったですが、後で追記致します。
ではまた！！！！