| /* ==================================================================== |
| Licensed to the Apache Software Foundation (ASF) under one or more |
| contributor license agreements. See the NOTICE file distributed with |
| this work for additional information regarding copyright ownership. |
| The ASF licenses this file to You under the Apache License, Version 2.0 |
| (the "License"); you may not use this file except in compliance with |
| the License. You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| ==================================================================== */ |
| |
| package org.apache.poi.poifs.macros; |
| |
| import java.io.File; |
| import java.io.FileNotFoundException; |
| import java.io.FileOutputStream; |
| import java.io.IOException; |
| import java.io.OutputStreamWriter; |
| import java.util.Map; |
| import java.util.Map.Entry; |
| |
| import org.apache.poi.util.StringUtil; |
| |
| /** |
| * This tool extracts out the source of all VBA Modules of an office file, |
| * both OOXML (eg XLSM) and OLE2/POIFS (eg DOC), to STDOUT or a directory. |
| * |
| * @since 3.15-beta2 |
| */ |
| public class VBAMacroExtractor { |
| public static void main(String args[]) throws IOException { |
| if (args.length == 0) { |
| System.err.println("Use:"); |
| System.err.println(" VBAMacroExtractor <office.doc> [output]"); |
| System.err.println(""); |
| System.err.println("If an output directory is given, macros are written there"); |
| System.err.println("Otherwise they are output to the screen"); |
| System.exit(1); |
| } |
| |
| File input = new File(args[0]); |
| File output = null; |
| if (args.length > 1) { |
| output = new File(args[1]); |
| } |
| |
| VBAMacroExtractor extractor = new VBAMacroExtractor(); |
| extractor.extract(input, output); |
| } |
| |
| /** |
| * Extracts the VBA modules from a macro-enabled office file and writes them |
| * to files in <tt>outputDir</tt>. |
| * |
| * Creates the <tt>outputDir</tt>, directory, including any necessary but |
| * nonexistent parent directories, if <tt>outputDir</tt> does not exist. |
| * If <tt>outputDir</tt> is null, writes the contents to standard out instead. |
| * |
| * @param input the macro-enabled office file. |
| * @param outputDir the directory to write the extracted VBA modules to. |
| * @param extension file extension of the extracted VBA modules |
| * @since 3.15-beta2 |
| */ |
| public void extract(File input, File outputDir, String extension) throws IOException { |
| if (! input.exists()) throw new FileNotFoundException(input.toString()); |
| System.err.print("Extracting VBA Macros from " + input + " to "); |
| if (outputDir != null) { |
| if (!outputDir.exists() && !outputDir.mkdirs()) { |
| throw new IOException("Output directory " + outputDir + " could not be created"); |
| } |
| System.err.println(outputDir); |
| } else { |
| System.err.println("STDOUT"); |
| } |
| |
| VBAMacroReader reader = new VBAMacroReader(input); |
| Map<String,String> macros = reader.readMacros(); |
| reader.close(); |
| |
| final String divider = "---------------------------------------"; |
| for (Entry<String, String> entry : macros.entrySet()) { |
| String moduleName = entry.getKey(); |
| String moduleCode = entry.getValue(); |
| if (outputDir == null) { |
| System.out.println(divider); |
| System.out.println(moduleName); |
| System.out.println(""); |
| System.out.println(moduleCode); |
| } else { |
| File out = new File(outputDir, moduleName + extension); |
| FileOutputStream fout = new FileOutputStream(out); |
| OutputStreamWriter fwriter = new OutputStreamWriter(fout, StringUtil.UTF8); |
| fwriter.write(moduleCode); |
| fwriter.close(); |
| fout.close(); |
| System.out.println("Extracted " + out); |
| } |
| } |
| if (outputDir == null) { |
| System.out.println(divider); |
| } |
| } |
| |
| /** |
| * Extracts the VBA modules from a macro-enabled office file and writes them |
| * to <tt>.vba</tt> files in <tt>outputDir</tt>. |
| * |
| * Creates the <tt>outputDir</tt>, directory, including any necessary but |
| * nonexistent parent directories, if <tt>outputDir</tt> does not exist. |
| * If <tt>outputDir</tt> is null, writes the contents to standard out instead. |
| * |
| * @param input the macro-enabled office file. |
| * @param outputDir the directory to write the extracted VBA modules to. |
| * @since 3.15-beta2 |
| */ |
| public void extract(File input, File outputDir) throws IOException { |
| extract(input, outputDir, ".vba"); |
| } |
| } |