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:
因此,问题来自模式:参数,在我的例子中是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:
因此,问题来自模式:参数,在我的例子中是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.
我希望这次经历能帮助别人。