■起因
色々な開発現場で、よくあることは成果物作成時にExcelファイルを最初開く際にシートのA1セルになっていることです。手動でやると手間かかり、ファイル本数が多いほどA1セルにすることの漏れも多いと思います。
ApacheのPOIを利用して指定フォルダ下の全ファイル、もしくは指定ファイルの各シートのA1セルに設定すれば便利かなと思いますので、簡単なプログラムを作りました。
(A1CELL_ROWとA1CELL_COLを修正すれば任意セルに設定可能)
■環境
OS:Windows
JREバージョン:1.8
POIバージョン:4.1.2
■ソースコード
package xxx.xxxxx.xxxx;//自分に好きに変更
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
public class A1CellJump {
//エクセルファイルを置いているフォルダー
private static String INPUT_DIR = ".\\";
private final int A1CELL_ROW = 0;
private final int A1CELL_COL = 0;
private final String EXCEL = ".xlsx";
public static void main(String[] args) throws IOException {
A1CellJump tt = new A1CellJump();
if (args.length > 0) {
INPUT_DIR = args[0];
}
List<String> fileList = tt.getFileList(INPUT_DIR);
for (int i = 0; i < fileList.size(); i++) {
tt.jumpA1Cell(fileList.get(i));
}
}
/**
* A1セルに移動する。<br>
* @param fileName ファイル名(フルパス)
*/
private void jumpA1Cell (String fileName) {
System.out.println("設定ファイル:"+ fileName);
// 変更するエクセルファイルを指定
FileInputStream in = null;
Workbook wb = null;
try {
in = new FileInputStream(fileName);
// 既存のエクセルファイルを編集する際は、WorkbookFactoryを使用
wb = WorkbookFactory.create(in);
} catch (Exception e) {
e.printStackTrace();
}
// 全シート名を取得する。
List<String> list = getSheetList(wb);
// シート毎のA1セルに移動する
for (int i = 0; i < list.size(); i++) {
String sheetName = list.get(i);
System.out.print("\tシート:"+ sheetName);
// 指定されたシートのA1セルを活性化にする。
activeA1Cell(wb.getSheet(sheetName));
}
FileOutputStream out = null;
try {
// 変更するエクセルファイルを指定
out = new FileOutputStream(fileName);
// 書き込み
wb.write(out);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {out.close();} catch (Exception e) {}
try {wb.close();} catch (Exception e) {}
}
}
/**
* 全シート名を取得する。<br>
* @param wkBook WorkBook
* @return 全シート名
*/
private List<String> getSheetList(Workbook wkBook) {
return IntStream.range(0, wkBook.getNumberOfSheets())
.mapToObj(wkBook::getSheetAt)
.map(Sheet::getSheetName)
.collect(Collectors.toList());
}
/**
* 指定されたシートのA1セルを活性化にする。<br>
* @param sheet シート
*/
private void activeA1Cell(Sheet sheet) {
Row row = sheet.getRow(A1CELL_ROW);
Cell cell = null;
if (row != null) {
cell = row.getCell(A1CELL_COL);
if (cell == null) {
cell = row.createCell(A1CELL_COL);
}
}
else {
row = sheet.createRow(A1CELL_ROW);
cell = row.createCell(A1CELL_COL);
}
cell.setAsActiveCell();
System.out.println(" OK");
}
/**
* 指定されたパスに存在する全てのExcelファイル名を取得する。<br>
* (指定されたパスがExcelファイルである場合、そのExcelファイル名を返す)<br>
* @param dir 取得するExcelファイルのパス
* @return Excelファイル名リスト
*/
private List<String> getFileList(String dir) {
List<String> fileList = new ArrayList<String>();;
Path p1 = Paths.get(dir);
if (dir.endsWith(EXCEL)) {
fileList.add(dir);
System.out.println(dir);
return fileList;
}
try {
Files.walkFileTree(p1, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
throws IOException
{
String fileName = file.toString();
if (fileName.endsWith(EXCEL)) {
fileList.add(file.toString());
System.out.println(file.toString());
}
return FileVisitResult.CONTINUE;
}
});
} catch (IOException e) {
e.printStackTrace();
}
return fileList;
}
}
■結果
ケース1:A1セルに値があり(BBB.xlsxのSheet1)
ケース2:A1セルに値がなし(BBB.xlsxのSheet2)
ケース3:A1セルが結合セル、値がなし(BBB.xlsxのSheet3)
ケース4:A1セルが結合セル、値があり(BBB.xlsxのSheet4)
--------コンソールに出力メッセージ-----------------
....\AAA.xlsx
....\BBB.xlsx
設定ファイル:....\AAA.xlsx
シート:Sheet1 OK
設定ファイル:....\BBB.xlsx
シート:Sheet1 OK
シート:Sheet2 OK
シート:Sheet3 OK
シート:Sheet4 OK