2016-10-07 2 views
2

Immer wenn ich eine Excel-Datei mit dem Apatche POI öffnen, wird die Datei geändert, obwohl ich gerade die Datei lese und keine Änderungen vornimmt.Apache POI - Lesen ändert Excel-Datei

Nehmen Sie zum Beispiel einen solchen Testcode.

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 immer fehl, da die Datei immer von Apache POI geändert wird. Beim Testen auf einer leeren Excel-Datei, die frisch mit MS Office erstellt wurde, schneidet Apache POI die Datei von 8,1 KB auf 6,2 KB ab und beschädigt die Datei.

Getestet mit:

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

und auch mit der Version 3.12

Kann ich verhindern, dass Apache POI aus mit anderen Mitteln meine Dateien modifiziert dann InputStream statt File vorbei. Ich möchte InputStream nicht passieren, weil ich über die Warnung von Apache besorgt bin, dass es mehr Gedächtnis nimmt und einige spezifische Anforderungen an die InputStream hat.

Antwort

4

Ihr Problem besteht darin, dass Sie das Readonly-Flag nicht übergeben, so dass Apache POI standardmäßig die Datei lesen/schreiben öffnet.

Sie benötigen die overloaded WorkbookFactory.create method which takes a readonly flag + eingestellt, dass nur lesbar Flagge auf true

Ändern Sie die Zeile

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

zu

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

und Ihre Datei nur lesbar mit nicht geöffnet werden zu verwenden, Änderungen

+0

Ich muss blind sein, weil irgendwie ich diese überladene Methode verpasst habe. Danke, dass du mich darauf hingewiesen hast :) – MJar