Java POINT 在使用 Maven 资源过滤器时发生 InvalidOperationException

Java POI occurs InvalidOperationException when using Maven resource filiter

我有一个读取 excel 模板的罐子。如果我使用Maven shade打包而不使用资源过滤器并执行我的jar,就可以了;但是,在使用 Maven 资源过滤器后,我遇到了一些异常!我执行jar时出现的异常如下:

2018-01-05 11:20:45,631 [main] INFO  tw.com.test.aop.SystemPointcuts- AOP Aro
und start : ServiceImpl.ServiceImpl.genExcel(..)(). param : 20171106,20171112
Exception in thread "main" org.apache.poi.openxml4j.exceptions.InvalidOperationE
xception: Can't open the specified file: 'C:\Users\seesaw\AppData\Local\Temp\Wee
klyTelecomAnalysis2553686971923113156.xlsx'
        at org.apache.poi.openxml4j.opc.ZipPackage.<init>(ZipPackage.java:131)
        at org.apache.poi.openxml4j.opc.OPCPackage.open(OPCPackage.java:246)
        at org.apache.poi.openxml4j.opc.OPCPackage.open(OPCPackage.java:200)
        at org.apache.poi.ss.usermodel.WorkbookFactory.create(WorkbookFactory.ja
va:90)
        at tw.com.test.weeklyTelecomAnalysis.service.ServiceImpl.genExcel(Ser
viceImpl.java:73)
        at tw.com.test.weeklyTelecomAnalysis.service.ServiceImpl$$FastClassBy
SpringCGLIB$d7f5cb8.invoke(<generated>)
        at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:2
04)
        at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation
.invokeJoinpoint(CglibAopProxy.java:738)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(
ReflectiveMethodInvocation.java:157)
        at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.p
roceed(MethodInvocationProceedingJoinPoint.java:85)
        at tw.com.test.aop.SystemPointcuts.execAround(SystemPointcuts.java:59
)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.
java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAcces
sorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMet
hodWithGivenArgs(AbstractAspectJAdvice.java:629)
        at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMet
hod(AbstractAspectJAdvice.java:618)
        at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAro
undAdvice.java:70)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(
ReflectiveMethodInvocation.java:179)
        at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invok
e(ExposeInvocationInterceptor.java:92)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(
ReflectiveMethodInvocation.java:179)
        at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterce
ptor.intercept(CglibAopProxy.java:673)
        at tw.com.test.weeklyTelecomAnalysis.service.ServiceImpl$$EnhancerByS
pringCGLIB$31d8a8.genExcel(<generated>)
        at tw.com.test.weeklyTelecomAnalysis.main.Entry.main(Entry.java:45)
Caused by: java.util.zip.ZipException: error in opening zip file
        at java.util.zip.ZipFile.open(Native Method)
        at java.util.zip.ZipFile.<init>(ZipFile.java:219)
        at java.util.zip.ZipFile.<init>(ZipFile.java:149)
        at java.util.zip.ZipFile.<init>(ZipFile.java:163)
        at org.apache.poi.openxml4j.opc.internal.ZipHelper.openZipFile(ZipHelper
.java:157)
        at org.apache.poi.openxml4j.opc.ZipPackage.<init>(ZipPackage.java:129)
        ... 23 more

这是我的 pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>tw.com.test</groupId>
    <artifactId>WeeklyTelecomAnalysis</artifactId>
    <packaging>jar</packaging>
    <version>1.0</version>
    <name>WeeklyTelecomAnalysis</name>

    <profiles>
        <profile>
            <id>prod</id>
            <properties>
                <pps.datasource>jdbc:oracle:thin:@11.111.11.111:1111:MYPROD</pps.datasource>
                <pps.username>xxxxxx</pps.username>
                <pps.password>xxxxxx</pps.password>
            </properties>
        </profile>
    </profiles>

    <properties>
        <!-- 執行類別 -->
        <mainClass>tw.com.test.weeklyTelecomAnalysis.main.Entry</mainClass>

        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <jdk.target.version>1.7</jdk.target.version>
        <maven.compiler.source>${jdk.target.version}</maven.compiler.source>
        <maven.compiler.target>${jdk.target.version}</maven.compiler.target>
        <org.springframework.version>4.3.8.RELEASE</org.springframework.version>
    </properties>

    <dependencies>
        <!-- Spring -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${org.springframework.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>${org.springframework.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>${org.springframework.version}</version>
        </dependency>

        <!-- commons -->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>com.springsource.org.apache.commons.dbcp</artifactId>
            <version>1.2.2.osgi</version>
        </dependency>

        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>com.springsource.org.apache.commons.lang</artifactId>
            <version>2.6.0</version>
        </dependency>

        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>com.springsource.org.apache.commons.pool</artifactId>
            <version>1.5.3</version>
        </dependency>

        <!-- mybatis -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.2.8</version>
        </dependency>

        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>1.2.2</version>
        </dependency>

        <!-- others -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.2</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.38</version>
        </dependency>

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

<!--         <dependency> -->
<!--            <groupId>org.apache.poi</groupId> -->
<!--            <artifactId>poi</artifactId> -->
<!--            <version>3.16</version> -->
<!--        </dependency> -->

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

        <!-- 安裝ojdbc6.jar至本地maven : mvn install:install-file -Dfile=ojdbc6.jar -DgroupId=com.oracle -DartifactId=ojdbc6 -Dversion=11.2.0 -Dpackaging=jar -->
        <dependency>    
            <groupId>com.oracle</groupId>    
            <artifactId>ojdbc6</artifactId>    
            <version>11.2.0</version>
        </dependency>

        <dependency>
            <groupId>org.junit</groupId>
            <artifactId>com.springsource.org.junit</artifactId>
            <version>4.9.0</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <repositories>
        <repository>
            <id>com.springsource.repository.bundles.external</id>
            <name>EBR External Release Repository</name>
            <url>http://repository.springsource.com/maven/bundles/external</url>
        </repository>
        <repository>
            <id>com.springsource.repository.libraries.external</id>
            <name>EBR Libraries Release Repository</name>
            <url>http://repository.springsource.com/maven/libraries/external</url>
        </repository>
    </repositories>

    <build>
        <finalName>WeeklyTelecomAnalysis</finalName>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <filtering>true</filtering>
            </resource>
        </resources>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>1.7.1</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                        <configuration>
                            <transformers>
                                <transformer
                                    implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                                    <mainClass>${mainClass}</mainClass>
                                </transformer>
                                <transformer
                                    implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
                                    <resource>META-INF/spring.handlers</resource>
                                </transformer>
                                <transformer
                                    implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
                                    <resource>META-INF/spring.schemas</resource>
                                </transformer>
                            </transformers>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>

这是我的应用程序-context.xml,它用于 spring 框架和 jdbc 配置,我使用 Maven 资源过滤器替换一些参数,但在我这样做之后,我得到了一些就是上面提到的错误。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context"
    xmlns:util="http://www.springframework.org/schema/util" xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:task="http://www.springframework.org/schema/task" xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
                        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
                        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
                        http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.0.xsd
                        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
                        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd
                        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">

    <!-- enable autowiring of components -->
    <context:component-scan base-package="tw.com.test" />
    <context:annotation-config />
    <aop:aspectj-autoproxy />

    <!-- MYPROD -->
    <bean id="pps_dataSource" class="org.apache.commons.dbcp.BasicDataSource"
        destroy-method="close" lazy-init="false">
        <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
        <property name="url" value="${pps.datasource}" />
        <property name="username" value="${pps.username}" />
        <property name="password" value="${pps.password}" />
        <property name="maxActive" value="20" />
        <property name="maxIdle" value="0" />
        <property name="maxWait" value="180000" />
        <property name="removeAbandoned" value="true" />
        <property name="removeAbandonedTimeout" value="300" />
        <property name="logAbandoned" value="true" />
        <property name="testOnBorrow" value="true" />
        <property name="testWhileIdle" value="true" />
        <property name="validationQuery" value="select 1 from dual" />
    </bean>

    <bean id="pps_sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="pps_dataSource" />
        <property name="configLocation" value="classpath:mybatis/sqlMapConfig.xml" />
    </bean>

    <bean id="pps_sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
        <constructor-arg index="0" ref="pps_sqlSessionFactory" />
    </bean>

    <bean id="pps_stsMapper" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="sqlSessionTemplateBeanName" value="pps_sqlSessionTemplate" />
        <property name="basePackage" value="tw.com.test.weeklyTelecomAnalysis.manual.pps" />
    </bean>
</beans>

这是读取 excel 模板的程序

public XSSFWorkbook genExcel(String fromDate, String toDate) throws Exception {
    // get Excel template
    Resource resource = new ClassPathResource("excel/WeeklyTelecomAnalysis.xlsx");
    File excel = stream2file(resource.getInputStream(), "WeeklyTelecomAnalysis", ".xlsx");
    XSSFWorkbook workbook = (XSSFWorkbook) WorkbookFactory.create(excel);

    // style
    this.setStyle(workbook);

    XSSFSheet sheet1 = workbook.getSheet("WeeklyTelecomAnalysis"); // template
    XSSFSheet sheet2 = workbook.createSheet("detail");

    // start
    createSheet1(sheet1, fromDate, toDate);
    createSheet2(sheet2, fromDate, toDate);

    return workbook;
}
public static File stream2file (InputStream in, String prefix, String suffix) throws IOException {
    final File tempFile = File.createTempFile(prefix, suffix);
    tempFile.deleteOnExit();
    try (FileOutputStream out = new FileOutputStream(tempFile)) {
        IOUtils.copy(in, out);
    }
    return tempFile;
}

谁能帮帮我?

您的 .xlsx 文件似乎包含一些不应被替换但被过滤替换的值,破坏了文件。

I just want to use "mvn clean package -Pprod"to filter the parameters that are url,username and password in the application-context.xml rather than the excel template.

鉴于此,就这样做

    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <filtering>false</filtering>
            <includes>
                <include>**/*.xlsx</include>
            </includes>
        </resource>
        <resource>
            <directory>src/main/resources</directory>
            <filtering>true</filtering>
            <includes>
                <include>**/*.xml</include>
            </includes>
        </resource>
    </resources>

仅过滤您的 xml 配置,将 excel 模板排除在外。