2016-10-07 3 views
2

Apatche POI를 사용하여 Excel 파일을 열 때마다 파일을 읽었을 때 수정을하지 않더라도 파일이 수정됩니다.아파치 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(); 
     } 
    } 
} 

테스트 readingShouldNotModifyFile 항상 아파치 POI에 의해 파일이 수정되므로 항상 실패합니다. MS Office로 새로 만든 빈 Excel 파일을 테스트 할 때 Apache POI는 파일을 8.1 kb에서 6.2 kb로 자르고 파일을 손상시킵니다.

과 함께 테스트 :

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

또한 버전 3.12

내가 그 대신 FileInputStream를 전달하는 다른 방법으로 내 파일을 수정 아파치 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