Index > Javaでzipを展開して、再度zipアーカイブを作成 ... OfficeOpenXMLデータの操作のために
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();
        }
    }
}
 Twitter
follow me on Twitter
 Categories