Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Which zipping library should I use to properly assemble a valid XLSX file in Objective-C?

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

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
  • Unzip the XLSX container with keeping the directory structure
  • Parse the corresponding sheet XML file (sheet2.xml in my case)
  • Add some rows
  • Rewrite the XML structure and save it
  • Put the updated XML file back into the XLSX container

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

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).

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

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?
  • If Objective-Zip is suitable, what is wrong with my code?

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".

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

like image 936
tolgamorf Avatar asked Mar 03 '13 21:03

tolgamorf


1 Answers

I found the answer upon doing some research and also having a one to one correspondence with Objective-Zip's developer, 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.

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: worksheets folder

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.

I hope this experience would help somebody out.

like image 83
tolgamorf Avatar answered Sep 28 '22 08:09

tolgamorf