模块背景:
客户端上传PDF文件,并可以在页面上显示。
解决思路:
1、利用SWFTools把PDF文件转为swf格式
2、利用FlexPaper显示转换后的swf文件
操作步骤:
1、下载并安装 SWFTools : http://www.swftools.org/download.html,根据你实际的操作系统选择对应的版本,我最终要部署在AIX上面,不知道麻不麻烦。这里现在Windows下测试。
2、下载FlexPaper:http://flexpaper.devaldi.com
3、对上传的PDF文件进行格式转换:pdf -->swf
public String getCommandStr(File pdfInputFile, String toFileFolder,String swfFileName) { //获取pdf2swf的安装路径,比如 D:\Program Files\\SWFTools String pdf2swf_path = AppConfig.getProperty("SWFTools.pdf2swf.installPath"); StringBuffer pdf2swf_command = null; if (pdf2swf_path != null && !pdf2swf_path.equals("")) { if (!pdf2swf_path.substring(pdf2swf_path.length() - 1, pdf2swf_path.length()).equals(File.separatorChar)) { pdf2swf_path += File.separatorChar; } else { log.error("未配置SWFTools的pdf2swf所在路径!"); } log.debug("#######pdf2swf_path:" + pdf2swf_path); pdf2swf_command = new StringBuffer(); //组装命令,注意空格 pdf2swf_command .append(pdf2swf_path) .append("pdf2swf ") .append(pdfInputFile) .append(" -o ") .append(toFileFolder) .append(File.separatorChar) .append(swfFileName); log.debug("pdf2swf_command:" + pdf2swf_command.toString()); } return pdf2swf_command.toString(); }
/** * 执行转换命令 * */ public void pdf2swf(String commandStr){ String commandStr_ = commandStr; ExecRunner exerun = new ExecRunner(); try { exerun.exec(commandStr_); } catch (IOException e) { log.error(e.getMessage()); } catch (InterruptedException e) { log.error(e.getMessage()); } }
上面用到的执行命令的ExecRunner是一个独立的java类,用来执行命令,好处是可以根据实际的操作系统来执行命令:
下面把这个文件贴出来:ExecRunner.java
// // This file is part of the OpenNMS(R) Application. // // OpenNMS(R) is Copyright (C) 2002-2003 The OpenNMS Group, Inc. All rights reserved. // OpenNMS(R) is a derivative work, containing both original code, included code and modified // code that was published under the GNU General Public License. Copyrights for modified // and included code are below. // // OpenNMS(R) is a registered trademark of The OpenNMS Group, Inc. // // For more information contact: // OpenNMS Licensing <[email protected]> // http://www.opennms.org/ // http://www.opennms.com/ // package com.syni.im800.kb.common.util; //////////////////////////////////////////////////////////////////////////////// // Copyright (C) 2002 Scott McCrory // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //////////////////////////////////////////////////////////////////////////////// import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.OutputStream; import java.io.PrintWriter; import java.io.StringWriter; import java.util.Date; import java.util.StringTokenizer; /** * <P> * Runs external executables, optionally under a watched thread. * * In addition, probably the most useful feature of ExecRunner is using it to * run a command-line program and obtain its stdout and stderr results in two * strings. This is done with exec(String) - see that method for an example. * * With acknowledgements to Michael C. Daconta, author of "Java Pitfalls, Time * Saving Solutions, and Workarounds to Improve Programs." and his article in * JavaWorld "When Runtime.exec() Won't". * </P> * * @author <a href="mailto:[email protected]">Scott McCrory </a>. * @version CVS $Id: ExecRunner.java,v 1.1.2.1 2011/08/10 01:53:25 linshutao Exp $ */ public class ExecRunner { /** Win NT/2K/MEPro require cmd.exe to run programs * */ private static final String WINDOWS_NT_2000_COMMAND_1 = "cmd.exe"; /** Win NT/2K/MEPro require the /C to specify what to run * */ private static final String WINDOWS_NT_2000_COMMAND_2 = "/C"; /** Win 9X/MEHome require cmd.exe to run programs * */ private static final String WINDOWS_9X_ME_COMMAND_1 = "command.exe"; /** Win 9X/MEHome require the /C to specify what to run * */ private static final String WINDOWS_9X_ME_COMMAND_2 = "/C"; /** String to send to STDERR if program exceeds max run time * */ private static final String MAX_RUN_TIME_EXCEEDED_STRING = "MAX_RUN_TIME_EXCEEDED"; /** String to capture STDOUT * */ private String out = new String(); /** String to capture STDERR * */ private String err = new String(); /** Default max run time (in seconds) * */ private int maxRunTimeSecs = 0; /** Flag to indicate if we've exceeded max run time * */ private boolean maxRunTimeExceeded = false; /** The name of this class for logging * */ private static final String CLASS_NAME = "ExecRunner"; /** The version of this class (filled in by CVS) * */ private static final String VERSION = "CVS $Revision: 1.1.2.1 {1}quot;; /** Number of miliseconds to wait between polling watched thread * */ private static final int POLL_DELAY_MS = 100; /** * Basic ExecRunner constructor. * */ public ExecRunner() { super(); } /** * ExecRunner constructor which also conveniently runs exec(String). * * @param command * The program or command to run * @throws ExceptionInInitializerError * thrown if a problem occurs */ public ExecRunner(String command) throws ExceptionInInitializerError { this(); try { exec(command); } catch (IOException ioe) { throw new ExceptionInInitializerError(ioe.getMessage()); } catch (InterruptedException inte) { throw new ExceptionInInitializerError(inte.getMessage()); } } /** * We override the <code>clone</code> method here to prevent cloning of * our class. * * @throws CloneNotSupportedException * To indicate cloning is not allowed * @return Nothing ever really returned since we throw a * CloneNotSupportedException */ public final Object clone() throws CloneNotSupportedException { throw new java.lang.CloneNotSupportedException(); } /** * The <B>exec(String) </B> method runs a process inside of a watched * thread. It returns the client's exit code and feeds its STDOUT and STDERR * to ExecRunner's out and err strings, where you then use getOutString() * and getErrString() to obtain these values. Example: * * <pre> * * // Execute the program and grab the results * try { * ExecRunner er = new ExecRunner(); * er.setMaxRunTimeSecs(5); * er.exec("ls -l"); * if (!er.getMaxRunTimeExceeded()) { * out = er.getOutString(); * err = er.getErrString(); * } else { * System.out.println("Maximum run time exceeded!"); * } * } catch (Exception e) { * System.out.println("Error executing " + program + ": " + e.getMessage()); * continue; * } * </pre> * * @return The command's return code * @param command * The program or command to run * @throws IOException * thrown if a problem occurs * @throws InterruptedException * thrown if a problem occurs */ public int exec(String command) throws IOException, InterruptedException { StringWriter swOut = new StringWriter(); PrintWriter pwOut = new PrintWriter(swOut, true); StringWriter swErr = new StringWriter(); PrintWriter pwErr = new PrintWriter(swErr, true); int rc = exec(command, pwOut, pwErr); out = swOut.toString(); err = swErr.toString(); return rc; } /** * Convenience method for calling exec with OutputStreams. * * @return The command's return code * @param command * The program or command to run * @param stdoutStream * java.io.OutputStream * @param stderrStream * java.io.OutputStream * @throws IOException * thrown if a problem occurs * @throws InterruptedException * thrown if a problem occurs */ public int exec(String command, OutputStream stdoutStream, OutputStream stderrStream) throws IOException, InterruptedException { PrintWriter pwOut = new PrintWriter(stdoutStream, true); PrintWriter pwErr = new PrintWriter(stderrStream, true); return exec(command, pwOut, pwErr); } /** * The <code>exec(String, PrintWriter, PrintWriter)</code> method runs a * process inside of a watched thread. It returns the client's exit code and * feeds its STDOUT and STDERR to the passed-in streams. * * @return The command's return code * @param command * The program or command to run * @param stdoutWriter * java.io.PrintWriter * @param stderrWriter * java.io.PrintWriter * @throws IOException * thrown if a problem occurs * @throws InterruptedException * thrown if a problem occurs */ public int exec(String command, PrintWriter stdoutWriter, PrintWriter stderrWriter) throws IOException, InterruptedException { // Default exit value is non-zero to indicate a problem. int exitVal = 1; // ////////////////////////////////////////////////////////////// Runtime rt = Runtime.getRuntime(); Process proc; String[] cmd = null; // First get the start time & calculate comparison numbers Date startTime = new Date(); long startTimeMs = startTime.getTime(); long maxTimeMs = startTimeMs + (maxRunTimeSecs * 1000); // ////////////////////////////////////////////////////////////// // First determine the OS to build the right command string String osName = System.getProperty("os.name"); if (osName.equals("Windows NT") || osName.equals("Windows 2000")) { cmd = new String[3]; cmd[0] = WINDOWS_NT_2000_COMMAND_1; cmd[1] = WINDOWS_NT_2000_COMMAND_2; cmd[2] = command; } else if (osName.equals("Windows 95") || osName.equals("Windows 98") || osName.equals("Windows ME")) { cmd = new String[3]; cmd[0] = WINDOWS_9X_ME_COMMAND_1; cmd[1] = WINDOWS_9X_ME_COMMAND_2; cmd[2] = command; } else { // Linux (and probably other *nixes) prefers to be called // with each argument supplied separately, so we first // Tokenize it across spaces as the boundary. StringTokenizer st = new StringTokenizer(command, " "); cmd = new String[st.countTokens()]; int token = 0; while (st.hasMoreTokens()) { String tokenString = st.nextToken(); // System.out.println(tokenString); cmd[token++] = tokenString; } } // Execute the command and start the two output gobblers if (cmd != null && cmd.length > 0) { // System.out.println("**Checkpoint** :" + cmd.length); proc = rt.exec(cmd); } else { throw new IOException("Insufficient commands!"); } StreamGobbler_ outputGobbler = new StreamGobbler_(proc.getInputStream(), stdoutWriter); StreamGobbler_ errorGobbler = new StreamGobbler_(proc.getErrorStream(), stderrWriter); outputGobbler.start(); errorGobbler.start(); // Wait for the program to finish running and return the // exit value obtained from the executable while (true) { try { exitVal = proc.exitValue(); break; } catch (IllegalThreadStateException e) { // If we get this exception, then the process isn't // done executing and we determine if our time is up. if (maxRunTimeSecs > 0) { Date endTime = new Date(); long endTimeMs = endTime.getTime(); if (endTimeMs > maxTimeMs) { // Time's up - kill the process and the gobblers and // return proc.destroy(); maxRunTimeExceeded = true; stderrWriter.println(MAX_RUN_TIME_EXCEEDED_STRING); outputGobbler.quit(); errorGobbler.quit(); return exitVal; } else { // Time is not up yet so wait 100 ms before testing // again Thread.sleep(POLL_DELAY_MS); } } } } // ////////////////////////////////////////////////////////////// // Wait for output gobblers to finish forwarding the output while (outputGobbler.isAlive() || errorGobbler.isAlive()) { } // ////////////////////////////////////////////////////////////// // All done, flush the streams and return the exit value stdoutWriter.flush(); stderrWriter.flush(); return exitVal; } /** * Returns the error string if exec(String) was invoked. * * @return The error string if exec(String) was invoked. */ public String getErrString() { return err; } /** * Returns whether the maximum runtime was exceeded or not. * * @return boolean indicating whether the maximum runtime was exceeded or * not. */ public boolean isMaxRunTimeExceeded() { return maxRunTimeExceeded; } /** * Returns the maximum run time in seconds for this object. * * @return the maximum run time in seconds for this object. */ public int getMaxRunTimeSecs() { return maxRunTimeSecs; } /** * Returns the output string if exec(String) was invoked. * * @return The output string if exec(String) was invoked. */ public String getOutString() { return out; } /** * This is for unit testing of the class. * * @param args * an array of command-line arguments * @throws IOException * thrown if a problem occurs */ public static void main(String[] args) throws IOException { try { ExecRunner er = new ExecRunner(); // /////////////////////////////////////////////////////////////////// // Linux: Test the exec operation with just STDOUT and STDERR // System.out.println("Testing ExecRunner with STDOUT and // STDERR..."); // er.exec("ls -l", System.out, System.err); // System.out.println("Complete"); // /////////////////////////////////////////////////////////////////// // Windows: Test the exec operation with just STDOUT and STDERR System.out.println("Testing ExecRunner with StringWriter..."); er = new ExecRunner(); er.setMaxRunTimeSecs(1); er.exec("dir /s c:\\"); // er.exec("ls -l"); System.out.println("<STDOUT>\n" + er.getOutString() + "</STDOUT>"); System.out.println("<STDERR>\n" + er.getErrString() + "</STDERR>"); System.out.println("Testing Done"); // /////////////////////////////////////////////////////////////////// // Exit nicely System.exit(0); } catch (Exception e) { e.printStackTrace(); System.exit(1); } } /** * We override the <code>readObject</code> method here to prevent * deserialization of our class for security reasons. * * @param in * java.io.ObjectInputStream * @throws IOException * thrown if a problem occurs */ private final void readObject(ObjectInputStream in) throws IOException { throw new IOException("Object cannot be deserialized"); } /** * Sets the maximum run time in seconds. If you do not want to limit the * executable's run time, simply pass in a 0 (which is also the default). * * @param max * Maximim number of seconds to let program run */ public void setMaxRunTimeSecs(int max) { maxRunTimeSecs = max; } /** * We override the <code>writeObject</code> method here to prevent * serialization of our class for security reasons. * * @param out * java.io.ObjectOutputStream * @throws IOException * thrown if a problem occurs */ private final void writeObject(ObjectOutputStream out) throws IOException { throw new IOException("Object cannot be serialized"); } }
如果成功转换为swf,那么下一步,部署FlexPaper:
把下载回来的FlexPaper复制到你项目的合适地方,我的FlexPaper版本是1.2.4,总共有下面文件:
js 文件夹、FlexPaperViewer.html、FlexPaperViewer.swf、Paper.swf
根据实际需要更改名字。
FlexPaperViewer.html里面根据我的需求进行了更改,主要就是设置swf文件路径,视图的大小等:
<script type="text/javascript"> var id_ = "${param.id}"; //获取id参数,根据项目存放swf的路径来构造swf的访问路径swfFilePath var swfFilePath = "/IM800KBS" + "/kbs_user_data/pdf/"+ id_ +"/"+id_+".swf"; <!-- For version detection, set to min. required Flash Player version, or 0 (or 0.0.0), for no version detection. --> var swfVersionStr = "9.0.124"; <!-- To use express install, set to playerProductInstall.swf, otherwise the empty string. --> var xiSwfUrlStr = "${expressInstallSwf}"; var flashvars = { SwfFile : escape(swfFilePath), Scale : 0.6, ZoomTransition : "easeOut", ZoomTime : 0.5, ZoomInterval : 0.1, FitPageOnLoad : false, FitWidthOnLoad : true, PrintEnabled : true, FullScreenAsMaxWindow : true, localeChain: "en_US" }; var params = { } params.quality = "high"; params.bgcolor = "#ffffff"; params.allowscriptaccess = "sameDomain"; params.allowfullscreen = "true"; var attributes = {}; attributes.id = "FlexPaperViewer"; attributes.name = "FlexPaperViewer"; swfobject.embedSWF( "FlexPaperViewer.swf", "flashContent", "800", "750", swfVersionStr, xiSwfUrlStr, flashvars, params, attributes); swfobject.createCSS("#flashContent", "display:block;text-align:left;"); </script>
接下里啊就可以访问页面了。