diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e4270c20..f4e30b60 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -37,7 +37,7 @@ jobs: java-version: ${{ matrix.java }} distribution: ${{ matrix.distribution }} - name: Cache local Maven repository - uses: actions/cache@v3 + uses: actions/cache@main with: path: ~/.m2/repository key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -46,7 +46,11 @@ jobs: - name: Chmod run: chmod +x mvnw - name: Test with Maven + if: ${{ matrix.java == '8' }} run: ./mvnw test -B -Dmaven.test.skip=false + - name: Test with Maven + if: ${{ matrix.java != '8' }} + run: ./mvnw test -B -Dmaven.test.skip=false -DargLine="--add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.base/sun.reflect.annotation=ALL-UNNAMED" - name: Maven Build run: ./mvnw install -B -V - name: Java Doc diff --git a/README.md b/README.md index baa22739..789337c2 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ easyexcel重写了poi对07版Excel的解析,一个3M的excel用POI sax解析 com.alibaba easyexcel - 4.0.0 + 4.0.1 ``` diff --git a/easyexcel-core/pom.xml b/easyexcel-core/pom.xml index f8179003..93d013cc 100644 --- a/easyexcel-core/pom.xml +++ b/easyexcel-core/pom.xml @@ -36,9 +36,5 @@ org.ehcache ehcache - - commons-io - commons-io - diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/util/EasyExcelTempFileCreationStrategy.java b/easyexcel-core/src/main/java/com/alibaba/excel/util/EasyExcelTempFileCreationStrategy.java new file mode 100644 index 00000000..ce4db733 --- /dev/null +++ b/easyexcel-core/src/main/java/com/alibaba/excel/util/EasyExcelTempFileCreationStrategy.java @@ -0,0 +1,136 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +package com.alibaba.excel.util; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.attribute.FileAttribute; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +import org.apache.poi.util.DefaultTempFileCreationStrategy; +import org.apache.poi.util.TempFileCreationStrategy; + +import static org.apache.poi.util.TempFile.JAVA_IO_TMPDIR; + +/** + * In the scenario where `poifiles` are cleaned up, the {@link DefaultTempFileCreationStrategy} will throw a + * java.nio.file.NoSuchFileException. Therefore, it is necessary to verify the existence of the temporary file every + * time it is created. + * + * @author Jiaju Zhuang + */ +public class EasyExcelTempFileCreationStrategy implements TempFileCreationStrategy { + /** + * Name of POI files directory in temporary directory. + */ + public static final String POIFILES = "poifiles"; + + /** + * To use files.deleteOnExit after clean JVM exit, set the -Dpoi.delete.tmp.files.on.exit JVM property + */ + public static final String DELETE_FILES_ON_EXIT = "poi.delete.tmp.files.on.exit"; + + /** + * The directory where the temporary files will be created (null to use the default directory). + */ + private volatile File dir; + + /** + * The lock to make dir initialized only once. + */ + private final Lock dirLock = new ReentrantLock(); + + /** + * Creates the strategy so that it creates the temporary files in the default directory. + * + * @see File#createTempFile(String, String) + */ + public EasyExcelTempFileCreationStrategy() { + this(null); + } + + /** + * Creates the strategy allowing to set the + * + * @param dir The directory where the temporary files will be created (null to use the default + * directory). + * @see Files#createTempFile(Path, String, String, FileAttribute[]) + */ + public EasyExcelTempFileCreationStrategy(File dir) { + this.dir = dir; + } + + private void createPOIFilesDirectory() throws IOException { + // Create our temp dir only once by double-checked locking + // The directory is not deleted, even if it was created by this TempFileCreationStrategy + if (dir == null || !dir.exists()) { + dirLock.lock(); + try { + if (dir == null || !dir.exists()) { + String tmpDir = System.getProperty(JAVA_IO_TMPDIR); + if (tmpDir == null) { + throw new IOException("System's temporary directory not defined - set the -D" + JAVA_IO_TMPDIR + + " jvm property!"); + } + Path dirPath = Paths.get(tmpDir, POIFILES); + dir = Files.createDirectories(dirPath).toFile(); + } + } finally { + dirLock.unlock(); + } + return; + } + } + + @Override + public File createTempFile(String prefix, String suffix) throws IOException { + // Identify and create our temp dir, if needed + createPOIFilesDirectory(); + + // Generate a unique new filename + File newFile = Files.createTempFile(dir.toPath(), prefix, suffix).toFile(); + + // Set the delete on exit flag, but only when explicitly disabled + if (System.getProperty(DELETE_FILES_ON_EXIT) != null) { + newFile.deleteOnExit(); + } + + // All done + return newFile; + } + + /* (non-JavaDoc) Created directory path is /poifiles/prefix0123456789 */ + @Override + public File createTempDirectory(String prefix) throws IOException { + // Identify and create our temp dir, if needed + createPOIFilesDirectory(); + + // Generate a unique new filename + File newDirectory = Files.createTempDirectory(dir.toPath(), prefix).toFile(); + + //this method appears to be only used in tests, so it is probably ok to use deleteOnExit + newDirectory.deleteOnExit(); + + // All done + return newDirectory; + } +} diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/util/FileUtils.java b/easyexcel-core/src/main/java/com/alibaba/excel/util/FileUtils.java index d800be51..f514f6f7 100644 --- a/easyexcel-core/src/main/java/com/alibaba/excel/util/FileUtils.java +++ b/easyexcel-core/src/main/java/com/alibaba/excel/util/FileUtils.java @@ -12,7 +12,6 @@ import java.util.UUID; import com.alibaba.excel.exception.ExcelAnalysisException; import com.alibaba.excel.exception.ExcelCommonException; -import org.apache.poi.util.DefaultTempFileCreationStrategy; import org.apache.poi.util.TempFile; /** @@ -111,7 +110,7 @@ public class FileUtils { /** * Write inputStream to file * - * @param file file + * @param file file * @param inputStream inputStream */ public static void writeToFile(File file, InputStream inputStream) { @@ -121,8 +120,8 @@ public class FileUtils { /** * Write inputStream to file * - * @param file file - * @param inputStream inputStream + * @param file file + * @param inputStream inputStream * @param closeInputStream closeInputStream */ public static void writeToFile(File file, InputStream inputStream, boolean closeInputStream) { @@ -154,11 +153,8 @@ public class FileUtils { } } - public static void createPoiFilesDirectory() { - File poiFilesPathFile = new File(poiFilesPath); - createDirectory(poiFilesPathFile); - TempFile.setTempFileCreationStrategy(new DefaultTempFileCreationStrategy(poiFilesPathFile)); + TempFile.setTempFileCreationStrategy(new EasyExcelTempFileCreationStrategy()); } public static File createCacheTmpFile() { @@ -171,7 +167,6 @@ public class FileUtils { } /** - * * @param directory */ public static File createDirectory(File directory) { diff --git a/easyexcel-support/pom.xml b/easyexcel-support/pom.xml index 85e5a533..f07d0446 100644 --- a/easyexcel-support/pom.xml +++ b/easyexcel-support/pom.xml @@ -24,8 +24,8 @@ 5.3.37 - org.springframework - spring-jcl + * + * @@ -49,7 +49,7 @@ true true - + org.springframework:spring-core @@ -63,6 +63,12 @@ + + + org.springframework + com.alibaba.excel.support + + diff --git a/easyexcel-test/pom.xml b/easyexcel-test/pom.xml index cd1bdb91..8c540b22 100644 --- a/easyexcel-test/pom.xml +++ b/easyexcel-test/pom.xml @@ -74,7 +74,7 @@ /com/alibaba/easyexcel/test/core/**/*.java - true + false diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/dataformat/DateFormatData.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/dataformat/DateFormatData.java index 5958161c..31cdd85d 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/dataformat/DateFormatData.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/dataformat/DateFormatData.java @@ -13,6 +13,7 @@ import lombok.Setter; public class DateFormatData { private String date; private String dateStringCn; + private String dateStringCn2; private String dateStringUs; private String number; private String numberStringCn; diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/dataformat/DateFormatTest.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/dataformat/DateFormatTest.java index 43a00fae..1229b238 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/dataformat/DateFormatTest.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/dataformat/DateFormatTest.java @@ -3,6 +3,7 @@ package com.alibaba.easyexcel.test.core.dataformat; import java.io.File; import java.util.List; import java.util.Locale; +import java.util.Objects; import com.alibaba.easyexcel.test.util.TestFileUtil; import com.alibaba.excel.EasyExcel; @@ -46,15 +47,22 @@ public class DateFormatTest { List list = EasyExcel.read(file, DateFormatData.class, null).locale(Locale.CHINA).sheet().doReadSync(); for (DateFormatData data : list) { - if (data.getDateStringCn() != null && !data.getDateStringCn().equals(data.getDate())) { - log.info("date:cn:{},{}", data.getDateStringCn(), data.getDate()); + if (!Objects.equals(data.getDateStringCn(), data.getDate()) && !Objects.equals(data.getDateStringCn2(), + data.getDate())) { + log.info("date:cn:{},{},{}", data.getDateStringCn(), data.getDateStringCn2(), data.getDate()); } if (data.getNumberStringCn() != null && !data.getNumberStringCn().equals(data.getNumber())) { log.info("number:cn{},{}", data.getNumberStringCn(), data.getNumber()); } } for (DateFormatData data : list) { - Assertions.assertEquals(data.getDateStringCn(), data.getDate()); + // The way dates are read in Chinese is different on Linux and Mac, so it is acceptable if it matches + // either one. + // For example, on Linux: 1-Jan -> 1-1月 + // On Mac: 1-Jan -> 1-一月 + Assertions.assertTrue( + Objects.equals(data.getDateStringCn(), data.getDate()) || Objects.equals(data.getDateStringCn2(), + data.getDate())); Assertions.assertEquals(data.getNumberStringCn(), data.getNumber()); } } diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/WriteV33Test.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/WriteV33Test.java index ed5b2385..5e83405d 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/WriteV33Test.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/WriteV33Test.java @@ -1,5 +1,8 @@ package com.alibaba.easyexcel.test.temp; +import java.io.File; +import java.nio.file.Files; +import java.nio.file.Path; import java.util.ArrayList; import java.util.Date; import java.util.List; @@ -135,4 +138,11 @@ public class WriteV33Test { return list; } + + @Test + public void test4() throws Exception{ + Path path= Files.createTempFile(new File("/Users/zhuangjiaju/test/test0422/test/xx").toPath(),System.currentTimeMillis()+"",".jpg"); + System.out.println(path); + } + } diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/large/TempLargeDataTest.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/large/TempLargeDataTest.java index b88bf06e..246656c1 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/large/TempLargeDataTest.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/large/TempLargeDataTest.java @@ -8,7 +8,6 @@ import java.util.ArrayList; import java.util.List; import java.util.stream.IntStream; -import com.alibaba.easyexcel.test.core.large.LargeDataTest; import com.alibaba.easyexcel.test.util.TestFileUtil; import com.alibaba.excel.EasyExcel; import com.alibaba.excel.ExcelWriter; @@ -31,7 +30,7 @@ import org.slf4j.LoggerFactory; public class TempLargeDataTest { - private static final Logger LOGGER = LoggerFactory.getLogger(LargeDataTest.class); + private static final Logger LOGGER = LoggerFactory.getLogger(TempLargeDataTest.class); private int i = 0; private static File fileFill07; diff --git a/easyexcel-test/src/test/resources/dataformat/dataformat.xls b/easyexcel-test/src/test/resources/dataformat/dataformat.xls index c8afd646..95c306ce 100644 Binary files a/easyexcel-test/src/test/resources/dataformat/dataformat.xls and b/easyexcel-test/src/test/resources/dataformat/dataformat.xls differ diff --git a/easyexcel-test/src/test/resources/dataformat/dataformat.xlsx b/easyexcel-test/src/test/resources/dataformat/dataformat.xlsx index f77dd9fd..34a05cc9 100644 Binary files a/easyexcel-test/src/test/resources/dataformat/dataformat.xlsx and b/easyexcel-test/src/test/resources/dataformat/dataformat.xlsx differ diff --git a/pom.xml b/pom.xml index 0a3da974..44dd0796 100644 --- a/pom.xml +++ b/pom.xml @@ -20,7 +20,7 @@ - 4.0.0 + 4.0.1 UTF-8 1.8 true @@ -113,11 +113,6 @@ ehcache 3.9.11 - - commons-io - commons-io - 2.11.0 - org.slf4j slf4j-api @@ -190,12 +185,12 @@ org.apache.maven.plugins maven-surefire-plugin - 2.22.2 + 3.3.0 org.apache.maven.plugins maven-shade-plugin - 3.2.4 + 3.6.0 org.codehaus.mojo @@ -235,11 +230,13 @@ com/alibaba/excel/metadata/DataFormatter.java com/alibaba/excel/util/DateUtils.java com/alibaba/excel/util/MapUtils.java + com/alibaba/excel/util/EasyExcelTempFileCreationStrategy.java com/alibaba/excel/metadata/format/DataFormatter.java com/alibaba/excel/metadata/format/ExcelGeneralNumberFormat.java com/alibaba/excel/metadata/csv/CsvDataFormat.java com/alibaba/excel/write/executor/ExcelWriteFillExecutor.java com/alibaba/excel/analysis/v07/handlers/sax/SharedStringsTableHandler.java + com/alibaba/excel/write/executor/ExcelWriteFillExecutor.java diff --git a/update.md b/update.md index b0fc5642..6b141fff 100644 --- a/update.md +++ b/update.md @@ -1,3 +1,8 @@ +# 4.0.1 + +* `commons-io` 修改为依赖 `poi`的版本 +* 修复临时目录被清理可能提示`NoSuchFileException`的异常 + # 4.0.0 * `poi`由`4.1.2`升级到`5.2.5`