Mon, March 9, 2009
Javaでzipを展開して、再度zipアーカイブを作成 ... OfficeOpenXMLデータの操作のために
MSOffice2007 では、docx,xlsx,pptx のように 拡張子に x が追加されているが、 この実体は、zip ファイルで中身はXML等で構成されている。 したがって、 データファイルだけを展開して中身を書きかえて、再度 zip アーカイブに戻してやれば、 MSOffice なしで、内容を操作することができる。
今回はそのためのJavaコード。
このサンプルでは中身の操作は一切しないで、単に既存の sample.pptx ファイルを作業ディレクトリに展開して、
その後、result.pptx ファイルにzipアーカイブとして保存しているだけ。
Test.java
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;
public class Test {
private static byte[] buf = new byte[1024];
private static final int EOF=-1;
private void addZipEntry(ZipOutputStream zos,String name,File file)
throws Exception{
if(file==null || file.exists()==false)
return ;
ZipEntry ent=new ZipEntry(name);
zos.putNextEntry(ent);
{
BufferedInputStream bin=
new BufferedInputStream( new FileInputStream(file) );
int c;
while( (c=bin.read()) != EOF){
zos.write( (byte)c );
}
bin.close();
}
zos.closeEntry();
}
public void copy(File inZipFile,File outZipFile) throws Exception{
File tmpdir=new File("tmp");
tmpdir.mkdirs();
ZipOutputStream zos=new ZipOutputStream(new FileOutputStream(outZipFile));
ZipFile zf=new ZipFile(inZipFile);
java.util.Enumeration enu=zf.entries();
while(enu.hasMoreElements()){
ZipEntry ze=(ZipEntry)enu.nextElement();
String name=ze.getName();
File f=new File(tmpdir,name);
f.getParentFile().mkdirs();
//System.out.println(name);
FileOutputStream fout=new FileOutputStream(f);
BufferedInputStream bin=new BufferedInputStream(zf.getInputStream(ze));
try{
for (;;) {
int len = bin.read(buf);
if (len < 0) break;
fout.write(buf, 0, len);
}
}
finally{
bin.close();
fout.close();
}
addZipEntry(zos,name,f);
}
zf.close();
zos.close();
delete(tmpdir);
}
static private void delete(File f){
if(f.isFile()){
f.delete();
}
if(f.isDirectory()){
File[] files=f.listFiles();
for(int i=0; i<files.length; i++){
delete( files[i] );
}
f.delete();
}
}
public static void main(String[] args) {
Test t=new Test();
try{
File in=new File("sample.pptx");
File out=new File("result.pptx");
t.copy(in,out);
}
catch(Exception ex){
ex.printStackTrace();
}
}
}