在Objective-C中,我应该使用哪个压缩库来正确地组装一个有效的XLSX文件?

时间:2022-09-07 08:13:22

I am trying to modify an XLSX file programmatically using Objective-C.

我正在尝试使用Objective-C修改XLSX文件。

So far, I am only modifying the data on one of the sheets. The steps I am taking are as follows:

到目前为止,我只修改了其中一张表上的数据。我采取的步骤如下:

  • Copy the XLSX file to Documents folder
  • 将XLSX文件复制到Documents文件夹
  • Unzip the XLSX container with keeping the directory structure
  • 解压XLSX容器,保留目录结构
  • Parse the corresponding sheet XML file (sheet2.xml in my case)
  • 解析相应的表XML文件(sheet2)。xml在我的例子中)
  • Add some rows
  • 添加一些行
  • Rewrite the XML structure and save it
  • 重写XML结构并保存它
  • Put the updated XML file back into the XLSX container
  • 将更新后的XML文件放回XLSX容器中

However, the new XLSX file becomes corrupt. I am using GDataXML for XML parsing/writing and Objective-Zip for zipping/unzipping.

但是,新的XLSX文件会损坏。我使用GDataXML进行XML解析/编写,使用Objective-Zip进行压缩/解压缩。

I know that the XML file I have created is proper, because when I manually unzip and the re-zip the corrupt XLSX file, it opens without any errors. I have done this on both OS X (using Unarchiver) and Windows (using 7-Zip).

我知道我创建的XML文件是正确的,因为当我手动解压并重新解压损坏的XLSX文件时,它会在没有任何错误的情况下打开。我在OS X(使用Unarchiver)和Windows(使用7-Zip)上都这样做过。

The problem is either with the Objective-Zip library, or the way I use it. Below is how I implement the zipping method:

问题是要么是Objective-Zip库,要么是我使用它的方式。下面是我如何实现zipping方法:

ZipFile *zipFile = [[ZipFile alloc] initWithFileName:XLSXDocumentsFilePath mode:ZipFileModeAppend];
ZipWriteStream *stream= [zipFile writeFileInZipWithName:XLSX_WORKSHEET_XML_SUBPATH compressionLevel:ZipCompressionLevelNone];
[stream writeData:data];
[stream finishedWriting];
[zipFile close];

I also tried the other compressionLevel arguments available with no luck:

我还尝试了其他压缩级别的参数,但运气不好:

ZipCompressionLevelDefault
ZipCompressionLevelBest
ZipCompressionLevelFastest

My questions are:

我的问题是:

  • Which zipping library should I use to create a valid XLSX file programmatically?
  • 我应该使用哪个压缩库来以编程方式创建一个有效的XLSX文件?
  • If Objective-Zip is suitable, what is wrong with my code?
  • 如果Objective-Zip是合适的,我的代码有什么问题?

From an answer to another question, I found out that: "The OOXML format imposes that the only compression method permitted in the package is DEFLATE".

从对另一个问题的回答中,我发现:“OOXML格式强制要求在包中允许的惟一压缩方法是紧缩”。

Is it possible to force Objective-Zip to use DEFLATE? Or is there an open-source iOS zipping library that uses DEFLATE?

是否有可能强制Objective-Zip使用紧缩?或者有一个开源的iOS压缩库可以使用DEFLATE吗?

1 个解决方案

#1


2  

I found the answer upon doing some research and also having a one to one correspondence with Objective-Zip's developer, flyingdolphinstudio.

我在做了一些研究后找到了答案,并与Objective-Zip的开发人员flyingdolphinstudio进行了一对一的通信。

First of all, Objective-Zip uses DEFLATE as the default compression method. I also confirmed this with the developer, who told me that using ZipCompressionLevelDefault, ZipCompressionLevelFastest or ZipCompressionLevelBest for the argument compressionLevel: will guarantee a DEFLATE compression.

首先,Objective-Zip使用DEFLATE作为默认的压缩方法。我也和开发人员确认了这一点,他们告诉我使用ZipCompressionLevelDefault、zipcompressionlevel最快或ZipCompressionLevelBest for the argument compressionLevel:将保证紧缩压缩。

So, the problem is coming from the mode: argument, which is ZipFileModeAppend in my case. It seems that MiniZip does not have a method to delete the files inside a zip file and that's why I am not overwriting the existing file, but adding a new one. To make it more clear, take a look at how my xl/worksheets folder look like after zipping it using Objective-Zip: 在Objective-C中,我应该使用哪个压缩库来正确地组装一个有效的XLSX文件?

因此,问题来自模式:参数,在我的例子中是ZipFileModeAppend。似乎MiniZip没有删除zip文件中的文件的方法,这就是为什么我没有覆盖现有文件,而是添加一个新的文件。为了让它更清晰,看看我的xl/worksheets文件夹在使用Objective-Zip压缩后的样子:

So, the only way to create a valid XLSX container is to create the zip file from scratch, by adding all the files and also keeping the directory/file structure intact.

因此,创建有效的XLSX容器的唯一方法是从头创建zip文件,方法是添加所有文件并保持目录/文件结构不变。

I hope this experience would help somebody out.

我希望这次经历能帮助别人。

#1


2  

I found the answer upon doing some research and also having a one to one correspondence with Objective-Zip's developer, flyingdolphinstudio.

我在做了一些研究后找到了答案,并与Objective-Zip的开发人员flyingdolphinstudio进行了一对一的通信。

First of all, Objective-Zip uses DEFLATE as the default compression method. I also confirmed this with the developer, who told me that using ZipCompressionLevelDefault, ZipCompressionLevelFastest or ZipCompressionLevelBest for the argument compressionLevel: will guarantee a DEFLATE compression.

首先,Objective-Zip使用DEFLATE作为默认的压缩方法。我也和开发人员确认了这一点,他们告诉我使用ZipCompressionLevelDefault、zipcompressionlevel最快或ZipCompressionLevelBest for the argument compressionLevel:将保证紧缩压缩。

So, the problem is coming from the mode: argument, which is ZipFileModeAppend in my case. It seems that MiniZip does not have a method to delete the files inside a zip file and that's why I am not overwriting the existing file, but adding a new one. To make it more clear, take a look at how my xl/worksheets folder look like after zipping it using Objective-Zip: 在Objective-C中,我应该使用哪个压缩库来正确地组装一个有效的XLSX文件?

因此,问题来自模式:参数,在我的例子中是ZipFileModeAppend。似乎MiniZip没有删除zip文件中的文件的方法,这就是为什么我没有覆盖现有文件,而是添加一个新的文件。为了让它更清晰,看看我的xl/worksheets文件夹在使用Objective-Zip压缩后的样子:

So, the only way to create a valid XLSX container is to create the zip file from scratch, by adding all the files and also keeping the directory/file structure intact.

因此,创建有效的XLSX容器的唯一方法是从头创建zip文件,方法是添加所有文件并保持目录/文件结构不变。

I hope this experience would help somebody out.

我希望这次经历能帮助别人。