2016-10-07 15 views
2

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> 

とも私が代わりにFileInputStreamを渡し、その後、他の手段で自分のファイルを変更するのはApache POIを防ぐことができます。私はInputStreamにいくつかの特定の要件があり、より多くのメモリを必要とするというApacheの警告を心配しているので、InputStreamを渡したくありません。

答えて

4

あなたの問題は、あなたがreadonlyフラグを渡していないことです。そのため、Apache POIはデフォルトでファイルの読み書きを開始しています。

あなたは何を読み取り専用開けませんoverloaded WorkbookFactory.create method which takes a readonly flag +真

変更にラインをその読み取り専用フラグを設定

try (InputStream is = new FileInputStream(testFile); Workbook wb = WorkbookFactory.create(is)) { 

try (IWorkbook wb = WorkbookFactory.create(testFile,null,true)) { 

にし、あなたのファイルを使用する必要があります変更

+0

私は盲目になっているはずです。どういうわけか、そのオーバーロードされたメソッドが見つかりませんでした。私にそれを指摘していただきありがとうございます:) – MJar

関連する問題