Submitted by: Sanjay Kumar Madhva, Srinidhi H. S., Pujari Yerriswamy (Sonata Software Ltd)
In a prior article on OpenXmlDeveloper.org, we demonstrated that it is possible to create a word document by creating a few XML files and assembling them into a package. That program will give you a feel for what goes into the document package.
In this article, we move on to some common tasks for working with Open XML Format documents. The utility below (with Java source code) provides a variety of useful functionality for creating and editing Open XML Format documents:
- Create a package (OpenXML Document).
- List out the parts contained in the Document.
- Delete file (part) from the package.
- Extract a file from the package.
- Extract all the files from the package.
- Add a new file into the package.
The above functionality will be very useful when you have to edit the document, and it is also a good example of various techniques for opening and working with documents stored in the Open XML Formats.
JAVA Document Utility
/*
* Created on Mar 22, 2006
* @author Srinidhi.H S / Sanjay.Kumar.M / Pujari Yerriswamy
* Sonata Software Limited.
*
*/
//package com.zip;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.zip.*;
public class OpenXMLDocumentFile
{
private final static String TEMP_SUFFIX = "temp";
private String srcZipFileName = "";
//Deletes Files from the Zip
// SourceZip = Provide Source zip file
// SplitString = Files to delete, Each file separated by a Split Character
// SplitBy = Split Character
public static void DeleteFiles(String SourceZip,
String SplitString,
String SplitBy)
{
String[] temp = null;
temp = SplitString.split(SplitBy);
List deleteFileList = new ArrayList();
for (int x = 0; x < temp.length; x++)
{
deleteFileList.add(temp[x]);
}
OpenXMLDocumentFile delFileObj = new OpenXMLDocumentFile();
//Zip file name
delFileObj.setSrcZipFileName(SourceZip);
//invoke the method to delete the files in the ZIP
delFileObj.deleteFileInZip(deleteFileList);
}
// Deletes Files from the Zip
// SourceZip = Provide Source zip file
// SplitString = Files to delete, Each file supprated by a Split Character
// SplitBy = Split Character
public static void DeleteFiles(String SourceZip, String DeleteFileName)
{
List deleteFileList = new ArrayList();
deleteFileList.add(DeleteFileName);
OpenXMLDocumentFile delFileObj = new OpenXMLDocumentFile();
//Zip file name
delFileObj.setSrcZipFileName(SourceZip);
//invoke the method to delete the files in the ZIP
delFileObj.deleteFileInZip(deleteFileList);
}
public void deleteFileInZip(List fileNames){
try{
File sourceZipFile = new File(getSrcZipFileName());
//Open the ZIP file for reading
ZipFile zipFile = new ZipFile(sourceZipFile,ZipFile.OPEN_READ);
//Get the entries
Enumeration enum = zipFile.entries();
List newZipEntries = new ArrayList();
while(enum.hasMoreElements())
{
ZipEntry zipEntry = (ZipEntry)enum.nextElement();
String currName = zipEntry.getName();
//Skip the files to be deleted
if(!fileNames.contains(currName)){
newZipEntries.add(zipEntry);
}
}
createZipFileToDelete(newZipEntries,zipFile);
zipFile.close();
//Delete the sourceZipFile
sourceZipFile.delete();
// rename tempZipFile and delete it
File tempFile = new File(getSrcZipFileName()+TEMP_SUFFIX);
tempFile.renameTo(sourceZipFile);
tempFile.delete();
}
catch(IOException ioe){
System.out.println("IOException occured====="+ioe);
ioe.printStackTrace();
}
}
private void createZipFileToDelete(List zipEntries, ZipFile zipFile)
throws IOException
{
ZipOutputStream zipOStream = new ZipOutputStream
(new FileOutputStream(getSrcZipFileName() + TEMP_SUFFIX));
zipOStream.setLevel(Deflater.BEST_COMPRESSION);
InputStream inStream;
for (int i = 0; i < zipEntries.size(); i++)
{
ZipEntry tempZipEntry = (ZipEntry)zipEntries.get(i);
zipOStream.putNextEntry(new ZipEntry(tempZipEntry.getName()));
inStream = zipFile.getInputStream(tempZipEntry);
int ch = 0;
while ((ch = inStream.read()) != -1)
{
zipOStream.write(ch);
}
zipOStream.closeEntry();
inStream.close();
}
zipOStream.flush();
zipOStream.close();
}
/**
* @return
*/
public String getSrcZipFileName()
{
return srcZipFileName;
}
/**
* @param string
*/
public void setSrcZipFileName(String string)
{
srcZipFileName = string;
}
// Create zipfile
// SourceZip = Provide Source zip file
// SplitString = Files to delete, Each file supprated by a Split Character
// SplitBy = Split Character
public static void Create(String zipFileName, String SplitString, String SplitBy)
{
String[] temp = null;
temp = SplitString.split(SplitBy);
List AddFileList = new ArrayList();
for (int x = 0; x < temp.length; x++)
{
AddFileList.add(temp[x]);
}
Create(zipFileName, AddFileList);
}
public static void Create(String zipFileName, List ToCompressFiles)
{
try
{
FileInputStream inStream;
FileOutputStream outStream = new FileOutputStream(zipFileName);
ZipOutputStream zipOStream = new ZipOutputStream(outStream);
zipOStream.setLevel(Deflater.BEST_COMPRESSION);
for (int loop = 0; loop < ToCompressFiles.size(); loop++)
{
inStream = new FileInputStream((String)ToCompressFiles.get(loop));
zipOStream.putNextEntry
(new ZipEntry((String)ToCompressFiles.get(loop)));
int i = 0;
while ((i = inStream.read()) != -1)
{
zipOStream.write(i);
}
zipOStream.closeEntry();
inStream.close();
}
zipOStream.flush();
zipOStream.close();
}
catch (IllegalArgumentException iae)
{
iae.printStackTrace();
}
catch (FileNotFoundException fe)
{
System.out.println("File not found====" + fe);
}
catch (IOException ioe)
{
System.out.println("IOException====" + ioe);
ioe.printStackTrace();
}
}
// Add the file into the zip
// SourceZip = Provide Source zip file
// addFileName = file to be added into the zip.
public static void Add(String SourceZip, String addFileName)
{
List addFileList = new ArrayList();
addFileList.add(addFileName);
OpenXMLDocumentFile addFileObj = new OpenXMLDocumentFile();
//invoke the method to Add the files to ZIP
addFileObj.Add(SourceZip, addFileList);
}
// Add the file into the zip
// SourceZip = Provide Source zip file
// SplitString = Files to add, Each file supprated by a Split Character
// SplitBy = Split Character
public static void Add(String zipFileName, String SplitString, String SplitBy)
{
String[] temp = null;
temp = SplitString.split(SplitBy);
List AddFileList = new ArrayList();
for (int x = 0; x < temp.length; x++)
{
AddFileList.add(temp[x]);
}
OpenXMLDocumentFile addFileObj = new OpenXMLDocumentFile();
//invoke the method to Add the files to ZIP
addFileObj.Add(zipFileName, AddFileList);
}
public void Add(String nameOfZip, List fileNamesToAdd)
{
File tempZip = null;
try
{
tempZip = File.createTempFile(nameOfZip + TEMP_SUFFIX, null); //
}
catch (IOException e)
{
System.err.println("Unable to create intermediate file.");
}
ZipFile zip = null;
try
{
zip = new ZipFile(nameOfZip);
}
catch (IOException e)
{
System.err.println("Unable to access original file.");
}
// Only rename file at end on success
boolean success = false;
try
{
ZipOutputStream newZip = new ZipOutputStream(new FileOutputStream(tempZip));
try
{
//Copy files
copyFiles(zip, newZip);
//Add new files
addNewFilesToZip(fileNamesToAdd, newZip);
success = true;
}
catch (IOException ex)
{
System.err.println("Operation aborted due to : " + ex);
}
finally
{
try
{
newZip.close();
}
catch (IOException ignored) { }
}
}
catch (IOException ex)
{
System.err.println("Can't access new file");
}
finally
{
try
{
zip.close();
}
catch (IOException ignored) { }
if (!success)
{
tempZip.delete();
}
}
if (success)
{
File origFile = new File(nameOfZip);
origFile.delete();
tempZip.renameTo(origFile);
}
}
private void addNewFilesToZip(List fileNamesToAdd, ZipOutputStream newZip)
throws FileNotFoundException, IOException
{
byte buffer[] = new byte[1024];
int bytesRead;
if (fileNamesToAdd != null && fileNamesToAdd.size() > 0)
{
FileInputStream fis = null;
for (int i = 0; i < fileNamesToAdd.size(); i++)
{
try
{
fis = new FileInputStream((String)fileNamesToAdd.get(i));
ZipEntry entry = new ZipEntry((String)fileNamesToAdd.get(i));
newZip.putNextEntry(entry);
while ((bytesRead = fis.read(buffer)) != -1)
{
newZip.write(buffer, 0, bytesRead);
}
}
catch (ZipException e)
{
String msg = (String)e.getMessage();
if (msg.indexOf("duplicate entry:") != -1)
{
System.err.println(msg);
continue;
}
}
finally
{
if (fis != null)
{
fis.close();
}
}
}
}
}
private void copyFiles(ZipFile zip, ZipOutputStream newZip) throws IOException
{
byte buffer[] = new byte[1024];
int bytesRead;
// Add back the original files
Enumeration entries = zip.entries();
while (entries.hasMoreElements())
{
// Prompt for copy
ZipEntry entry = (ZipEntry)entries.nextElement();
String name = entry.getName();
InputStream is = zip.getInputStream(entry);
newZip.putNextEntry(new ZipEntry(name));
while ((bytesRead = is.read(buffer)) != -1)
{
newZip.write(buffer, 0, bytesRead);
}
}
}
public static void ExtractAll(String zipFileName, String ToExtractFile)
{
try
{
File sourceZipFile = new File(zipFileName);
File destDirectory = new File(ToExtractFile);
//Open the ZIP file for reading
ZipFile zipFile = new ZipFile(sourceZipFile,ZipFile.OPEN_READ);
//Get the entries
Enumeration enum = zipFile.entries();
while(enum.hasMoreElements())
{
ZipEntry zipEntry = (ZipEntry)enum.nextElement();
String currName = zipEntry.getName();
File destFile = new File(destDirectory,currName);
// grab file's parent directory structure
File destinationParent = destFile.getParentFile();
// create the parent directory structure if needed
destinationParent.mkdirs();
if(!zipEntry.isDirectory())
{
BufferedInputStream is = new
BufferedInputStream(zipFile.getInputStream(zipEntry));
int currentByte;
// write the current file to disk
FileOutputStream fos = new FileOutputStream(destFile);
BufferedOutputStream dest = new BufferedOutputStream(fos);
// read and write until last byte is encountered
while ((currentByte = is.read()) != -1)
{
dest.write(currentByte);
}
dest.flush();
dest.close();
is.close();
}
}
}
catch(IOException ioe)
{
System.out.println("IOException occured====="+ioe);
ioe.printStackTrace();
}
}
// Display the list of files present int the document
public static void DisplayFiles(String zipFileName)
{
String[] TempString = ListFiles(zipFileName);
for (int x = 0; x < TempString.length; x++)
{
System.out.println(TempString[x]);
}
}
// return a list of files in the zip as an array of strings
public static String[] ListFiles(String zipFileName)
{
List _tempString = null;
_tempString = FilesList(zipFileName);
String[] retarray = new String[_tempString.size()];
for (int i = 0; i < _tempString.size(); i++)
{
retarray[i] = (String)_tempString.get(i);
}
return retarray;
}
// return a list of files in the zip as an List
public static List FilesList(String zipFileName)
{
try
{
List _tempString = new ArrayList();
File sourceZipFile = new File(zipFileName);
//Open the ZIP file for reading
ZipFile zipFile = new ZipFile(sourceZipFile,ZipFile.OPEN_READ);
//Get the entries
Enumeration enum = zipFile.entries();
while(enum.hasMoreElements())
{
ZipEntry zipEntry = (ZipEntry)enum.nextElement();
String currName = zipEntry.getName();
_tempString.add(currName);
}
return _tempString;
}
catch(IOException ioe)
{
System.out.println("IOException occured====="+ioe);
ioe.printStackTrace();
return null;
}
}
// Extract one file out of the zip file
// zipFileName =
// ToExtractFile = The file that needs to be extracted.
// FolderToExtractIn = Folder into which the extract file as to be placed
public static void ExtractFile(String zipFileName, String ToExtractFile,
String FolderToExtractIn)
{
try
{
File sourceZipFile = new File(zipFileName);
File destDirectory = new File(FolderToExtractIn);
//Open the ZIP file for reading
ZipFile zipFile = new ZipFile(sourceZipFile,ZipFile.OPEN_READ);
//Get the entries
Enumeration enum = zipFile.entries();
while(enum.hasMoreElements())
{
ZipEntry zipEntry = (ZipEntry)enum.nextElement();
String currName = zipEntry.getName();
if (currName.equals(ToExtractFile))
{
File destFile = new File(destDirectory,currName);
// grab file's parent directory structure
File destinationParent = destFile.getParentFile();
// create the parent directory structure if needed
destinationParent.mkdirs();
if(!zipEntry.isDirectory())
{
BufferedInputStream is = new
BufferedInputStream(zipFile.getInputStream(zipEntry));
int currentByte;
// write the current file to disk
FileOutputStream fos = new FileOutputStream(destFile);
BufferedOutputStream dest = new BufferedOutputStream(fos);
// read and write until last byte is encountered
while ((currentByte = is.read()) != -1)
{
dest.write(currentByte);
}
dest.flush();
dest.close();
is.close();
}
}
}
}
catch(IOException ioe)
{
System.out.println("IOException occured====="+ioe);
ioe.printStackTrace();
}
}
public static void main(String args[])
{
if (args.length > 0)
{
if (args[0].equals("-L") || args[0].equals("-l"))
{
DisplayFiles(args[1]);
}
else if (args[0].equals("-D") || args[0].equals("-d"))
{
if (args.length == 4)
{
DeleteFiles(args[1], args[2], args[3]);
}
else if (args.length == 3)
{
DeleteFiles(args[1], args[2]);
}
}
else if (args[0].equals("-U") || args[0].equals("-u"))
{
ExtractAll(args[1], args[2]);
}
else if (args[0].equals("-E") || args[0].equals("-e"))
{
ExtractFile(args[1], args[2], args[3]);
}
else if (args[0].equals("-c") || args[0].equals("-C"))
{
Create(args[1], args[2], args[3]);
}
else if (args[0].equals("-A") || args[0].equals("-a"))
{
if (args.length == 4)
{
Add(args[1], args[2], args[3]);
}
else if (args.length == 3)
{
Add(args[1], args[2]);
}
}
else
{
DisplayUsage();
}
}
else
{
DisplayUsage();
}
}
// This will be used by the main application block to display how to use this application
private static void DisplayUsage()
{
System.out.println("Usage ----------------------------------------------------");
System.out.println("");
System.out.println("To List file in the Document");
System.out.println("");
System.out.println(" Java OpenXMLDocumentFile -L ");
System.out.println("");
System.out.println("To Delete file from the Document");
System.out.println(" Option 1 :");
System.out.println("");
System.out.println(" Java OpenXMLDocumentFile -D ");
System.out.println(" Option 2 :");
System.out.println("");
System.out.println(" Java OpenXMLDocumentFile -D \" ");
System.out.println("");
System.out.println("Extract one File From Zip");
System.out.println("");
System.out.println(" Java OpenXMLDocumentFile -E ");
System.out.println("");
System.out.println("To Add file from the Document");
System.out.println(" Option 1 :");
System.out.println("");
System.out.println(" Java OpenXMLDocumentFile -a ");
System.out.println(" Option 2 :");
System.out.println("");
System.out.println(" Java OpenXMLDocumentFile -a \"