Apatche POIを使用してExcelファイルを開くときは、ファイルを読んでいて変更を加えなくてもファイルが変更されます。Apache POI - 読書ファイルを変更する
たとえば、そのようなテストコードを取ります。
public class ApachePoiTest {
@Test
public void readingShouldNotModifyFile() throws Exception {
final File testFile = new File("C:/work/src/test/resources/Book2.xlsx");
final byte[] originalChecksum = calculateChecksum(testFile);
Assert.assertTrue("Calculating checksum modified file",
MessageDigest.isEqual(originalChecksum, calculateChecksum(testFile)));
try (Workbook wb = WorkbookFactory.create(testFile)) {
Assert.assertNotNull("Reading file with Apache POI", wb);
}
Assert.assertTrue("Reading file with Apache POI modified file",
MessageDigest.isEqual(originalChecksum, calculateChecksum(testFile)));
}
@Test
public void readingInputStreamShouldNotModifyFile() throws Exception {
final File testFile = new File("C:/work/src/test/resources/Book2.xlsx");
final byte[] originalChecksum = calculateChecksum(testFile);
Assert.assertTrue("Calculating checksum modified file",
MessageDigest.isEqual(originalChecksum, calculateChecksum(testFile)));
try (InputStream is = new FileInputStream(testFile); Workbook wb = WorkbookFactory.create(is)) {
Assert.assertNotNull("Reading file with Apache POI", wb);
}
Assert.assertTrue("Reading file with Apache POI modified file",
MessageDigest.isEqual(originalChecksum, calculateChecksum(testFile)));
}
private byte[] calculateChecksum(final File file) throws Exception {
final MessageDigest md = MessageDigest.getInstance("MD5");
md.reset();
try (InputStream is = new FileInputStream(file)) {
final byte[] bytes = new byte[2048];
int numBytes;
while ((numBytes = is.read(bytes)) != -1) {
md.update(bytes, 0, numBytes);
}
return md.digest();
}
}
}
ファイルは常にApacheのPOIによって変更されますので、テストreadingShouldNotModifyFile
は常に、失敗します。 Microsoft Officeで新しく作成された空のExcelファイルをテストする場合、Apache POIはファイルを8.1 kbから6.2 kbに切り詰めてファイルを破損させます。でテスト
:
バージョン3.12と
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.15</version>
</dependency>
とも私が代わりにFile
のInputStream
を渡し、その後、他の手段で自分のファイルを変更するのはApache POIを防ぐことができます。私はInputStream
にいくつかの特定の要件があり、より多くのメモリを必要とするというApacheの警告を心配しているので、InputStream
を渡したくありません。
私は盲目になっているはずです。どういうわけか、そのオーバーロードされたメソッドが見つかりませんでした。私にそれを指摘していただきありがとうございます:) – MJar