部分/_rels/.rels没有任何内容类型!规则:从包中检索零件时,包需要内容类型。 [M.1.14]

时间:2017-08-30 02:09:35

标签: java excel

POI-3.16.jar POI-OOXML-3.16.jar POI-OOXML-架构 - 3.16.jar

当我运行' main'有些麻烦

public static void main(String[] args) {
        try {  
              POIFSFileSystem fs = new POIFSFileSystem();  
              EncryptionInfo info = new EncryptionInfo(EncryptionMode.agile);  
//            EncryptionInfo info = new EncryptionInfo(EncryptionMode.agile,  CipherAlgorithm.aes256, HashAlgorithm.md5, -1, -1, null);
              Encryptor enc = info.getEncryptor();  
              enc.confirmPassword("foobaa");  

               OPCPackage opc = OPCPackage.open(new File("e:/test/test.xlsx"), PackageAccess.READ_WRITE);  
              //OPCPackage opc = OPCPackage. .create(FileOutputStream);  
              OutputStream os = enc.getDataStream(fs);  

              opc.save(os);  
              opc.close();  

              FileOutputStream fos = new FileOutputStream("e:/test/test.xlsx");  
              fs.writeFilesystem(fos);  
              fos.close();  

            } catch (Exception e) {  
              e.printStackTrace();  
            }  
    }

错误消息:org.apache.poi.openxml4j.exceptions.InvalidFormatException:部分/_rels/.rels没有任何内容类型!规则:从包中检索零件时,包需要内容类型。 [M.1.14]

请帮助我谢谢

1 个答案:

答案 0 :(得分:0)

This bug可能与之相关,并且可以通过升级到较新版本的Xalan来解决。


但是,当OPCPackage API意外修改模板输入文件时,我遇到了该错误。

TL; DR-尝试使用File或InputStream构造函数而不是OPCPackage

根据XSSFWorkbook构造函数的JavaDoc中的建议更改构造函数时,我遇到了POI 4.1.2的错误:

XSSFWorkbook wb = new XSSFWorkbook(new FileInputStream(myFile))

try (OPCPackage pkg = OPCPackage.open(myFile);
     XSSFWorkbook wb = new XSSFWorkbook(pkg)) {

就我而言,myFile是模板文件,我不希望对其进行修改。但是,在第二次运行代码时,我会收到该错误:

/_rels/.rels部分没有任何内容类型!规则:从包装中检索零件时,包装要求内容类型。 [M.1.14]

当我尝试再次读取模板文件(myFile)时,我注意到myFile被修改并导致该错误。如果您不希望写入文件,则可以通过几种不同的方式将其设为只读:

我转到OPCPackage.open(template, PackageAccess.READ)

不允许操作,文档以只读模式打开! 即使我不希望该文件被修改。

使用chmod -w(和默认的PackageAccess.READ_WRITE),您可以看到POI尝试执行写操作的地方。

在调试时,我注意到了这个TODO,可能是Bug? org.apache.poi.ooxml.POIXMLDocument#write

    public final void write(OutputStream stream) throws IOException {
        OPCPackage p = getPackage();
        if(p == null) {
            throw new IOException("Cannot write data, document seems to have been closed already");
        }
        
        //force all children to commit their changes into the underlying OOXML Package
        // TODO Shouldn't they be committing to the new one instead?
        Set<PackagePart> context = new HashSet<>();
        onSave(context);
        context.clear();

        //save extended and custom properties
        getProperties().commit();

        p.save(stream);
    }

如果您不希望它修改文件,则可能还想尝试使用revert()中的close()而不是OPCPackage