2016-10-07 5 views
2

Всякий раз, когда я открываю файл excel с использованием POI Apatche, файл изменяется, хотя я просто читаю файл и не делаю никаких изменений.Apache POI - чтение изменяет файл excel

Возьмите, например, такой контрольный код.

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(); 
     } 
    } 
} 

Test readingShouldNotModifyFile всегда терпит неудачу, потому что файл будет всегда модифицируется Apache POI. Более того, при тестировании на чистый файл excel, недавно созданный с помощью MS Office, Apache POI разрезает файл с 8.1 кб до 6.2 кб и развращает файл.

Протестирован:

<dependency> 
    <groupId>org.apache.poi</groupId> 
    <artifactId>poi-ooxml</artifactId> 
    <version>3.15</version> 
</dependency> 

, а также с версией 3.12

Могу ли я предотвратить Apache POI от изменения моих файлов с помощью других средств с последующим пропусканием InputStream вместо File. Я не хочу передавать 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

Смежные вопросы