freemarker生成world转PDF转SWF,加载到浏览器.解决最终浏览器加载的是xml代码的问题.
来源:互联网 发布:linux socket句柄 取值 编辑:程序博客网 时间:2024/05/19 23:10
freemarker生成world转PDF转SWF,加载到浏览器.解决最终浏览器加载的是xml代码的问题.
首先说一下需求:动态生成world,客户可在浏览器预览freemarker动态生成的world文档.
失败的解决方法:
1. world转xml, 编辑xml,用${}替换动态改变的值。
2. freemarker动态替换${}占位符的值, 更改后缀名为doc。
3. 系统安装openoffice工具,启动openoffice服务,jodconverter 调用命令将doc转成pdf.
4. 系统安装swftools工具, 调用命令,将pdf转成swf.(很多插件支持直接加载pdf到浏览器,但是对于老版本的IE,兼容性并不好,但是swf文件基本所有浏览器都支持,所以为了老版本ie兼容性,就做了一步转swf)
5. 前台js插件flashPaper,直接加载服务器上的swf文件.
最终效果, doc和pdf文档直接双击可以打开,显示的也正常。但是flashPaper加载到浏览器则显示的是一堆xml格式代码,这个代码就是freemarker生成的doc右键文本打开后的xml代码. 经过翻阅资料,flashPaper包括很多插件不支持直接加载xml形式的doc文档(可能是我没找到正确方法,如果您有, 请给留个言,谢谢),如果非要加载,那么显示到浏览器上的就会是一推xml代码。主要原因可能是freemarker产生的doc实际上只是个xml文档,右键可打开文本查看,但是直接在桌面新建的doc,docx文档右键则打不开(实际上这样建立的doc docx是一个压缩文件)
新的解决方法:
1. 新建docx文档(07版本的), 编辑docx,需要用freemarker替换的数据用${x}代替,保存 注意: 替换变量${x}时最好一次性写完,要不可能xml文档混乱
2. 右键以压缩文件形式打开,在world/下找到document.xml文件,是freemarker需要输出的结果xml文件.格式化xml查看${}占位是否有问题,有问题
不要直接改,重新编辑world,重复1步骤开始。
3. 第2步没问题,将docx文件和导出来的xml文件复制到ftl/test下,xml重命名为docx的名字.(我建立的是javaweb项目,ftl/test是在类路径下,以方便
根据类路径可读取到这个包)
4. FreemarkerUtil.printFile 根据第三步的xml生成替换后新的xml,临时保存
5. XmlToDocxDocument.printDocx 根据第三步docx模板文件,用新的xml替换调/world下document文件,重新生成一个新的docx。
6. 系统安装openoffice工具,启动openoffice服务,jodconverter 调用命令将docx转成pdf.
4. 系统安装swftools工具, 调用命令,将pdf转成swf.(很多插件支持直接加载pdf到浏览器,但是对于老版本的IE,兼容性并不好,但是swf文件基本所
有浏览器都支持,所以为了老版本ie兼容性,就做了一步转swf)
5. 前台js插件flashPaper,直接加载服务器上的swf文件.
经测试效果良好,IE7 到 11,火狐 谷歌多种内核浏览器均可正常显示.
大致方法就是doc中包含一个xml文档,xml文档包含了所有要显示的内容,我们用freemarker替换这个xml,之后再添加压缩文件,替换回去。这样最终保持了
world的完整性,新建文档需要docx 07版的。
代码: 完整项目有附件. 点击打开链接
需要安装的软件,资源很多 随处可下
1. Apache_OpenOffice_4.1.4_Win_x86_install_zh-CN.exe
2. swftools-0.9.0.exe
jar 包
1.
/*** @date 2017年11月21日 下午11:10:14 * @return void 返回类型 * @throws Exception * @throws* @Description:* 下载文档(freemarker模板) */@RequestMapping(value="/downLoadDocx")@ResponseBodypublic void downLoadDocument(HttpServletResponse response, String fileName) throws Exception{/** * 1. freemarker填充xml文件 * 2. xml替换docx模板中的document * 3. 下载 */Map<String, Object> root = new HashMap<String, Object>();root.put("userName", "丽丽");root.put("sex", "2女");root.put("content", "这是freemarker模板引擎生成的world测试内容.");String preFileName = fileName;//前台传过来的文件名 test.docxString ftlPath = "test";//ftl下的文件夹名称String filePath = PathUtil.getDocumentPathByClassPath();//webcontent/document目录String timeFileName = FileUtil.getFilePrefixName(fileName)+(new Date().getTime())+".xml";FreemarkerUtil.printFile(FileUtil.getFilePrefixName(fileName)+".xml", root, timeFileName, filePath, ftlPath);XmlToDocxDocument.printDocx(response, filePath+timeFileName,PathUtil.getClassResources()+"/ftl/"+ftlPath+"/"+preFileName,ConfigUtil.getSwfUploadDir() + "/"+preFileName,preFileName);//删除临时freemarker生成的xml文件FileUtil.delFile(filePath+timeFileName);}
2. freemarker的代码就不贴了, 想用就看附件项目吧,看下java zip的处理XmlToDocxDocument.printDocx, 遇到document.xml文件,则替换,否则不懂,直接输出
import java.io.File;import java.io.FileInputStream;import java.io.IOException;import java.io.InputStream;import java.util.Enumeration;import java.util.zip.ZipEntry;import java.util.zip.ZipException;import java.util.zip.ZipFile;import java.util.zip.ZipOutputStream;import javax.servlet.http.HttpServletResponse;/** * 将freemarker替换的xml转成docx压缩文件的document.xml * @author yangwl 2017年11月23日21:56:19 * */public class XmlToDocxDocument {/*** @date 2017年11月23日 下午9:57:30 * documentFile freemarker替换之后的xml* docxTemplate docx的模板* toFilePath 导出目标文件路径* @return void 返回类型* @throws* @Description: */public static void printDocx(HttpServletResponse response, File documentFile, String docxTemplate, String toFilePath) throws ZipException, IOException {try {File docxFile = new File(docxTemplate);ZipFile zipFile = new ZipFile(docxFile);Enumeration<? extends ZipEntry> zipEntrys = zipFile.entries();ZipOutputStream zipout = new ZipOutputStream(response.getOutputStream());int len = -1;byte[] buffer = new byte[1024];while (zipEntrys.hasMoreElements()) {ZipEntry next = zipEntrys.nextElement();InputStream is = zipFile.getInputStream(next);// 把输入流的文件传到输出流中 如果是word/document.xml由我们输入zipout.putNextEntry(new ZipEntry(next.toString()));if ("word/document.xml".equals(next.toString())) {InputStream in = new FileInputStream(documentFile);while ((len = in.read(buffer)) != -1) {zipout.write(buffer, 0, len);}in.close();} else {while ((len = is.read(buffer)) != -1) {zipout.write(buffer, 0, len);}is.close();}}zipout.close();} catch (Exception e) {e.printStackTrace();}}public static void printDocx(HttpServletResponse response, String documentFile, String docxTemplate, String toFilePath, String outFileName) throws ZipException, IOException {response.reset(); response.setHeader("Content-Disposition", "attachment; filename=\"" + new String(outFileName.getBytes("gb2312"), "ISO8859-1")+ "\""); response.setContentType("application/octet-stream;charset=UTF-8"); printDocx(response, new File(documentFile), docxTemplate, toFilePath);response.flushBuffer();}}
3. 页面显示:
/** * 文档预览 * world/excel/ppt 等 -> PDF -> SWF * swf兼容个版本浏览器 * 2017年11月16日14:31:16 * @param os * @param filePath * @throws IOException */ @RequestMapping(value="/showDocx", method=RequestMethod.GET) public void showOfficeFile(OutputStream os,String filePath) throws IOException { if (!StringUtil.isEmpty(filePath)){ filePath = ConfigUtil.getSwfUploadDir() + "/" + filePath; String swfFilePath = filePath.substring(0, filePath.lastIndexOf(".")) + ".swf"; File f = new File(swfFilePath); boolean hasFile = true; if (!f.exists()) { LOGGER.info("未生成过swf文件,即将生成的SWF文件,路径为: " + swfFilePath); hasFile = OfficeToSwf.toSwf(filePath); } LOGGER.info("SWF文件已生成,路径为: " + swfFilePath); if ( hasFile ){ InputStream inputStream = null; inputStream = new BufferedInputStream(new FileInputStream(f)); FileCopyUtils.copy(inputStream,os); os.flush(); os.close(); inputStream.close(); } } }
docx-pdf
public static int office2PDF(String sourceFile, String destFile){ try { log.debug("文件转换为PDF,[参数]SOURCEFile: " + sourceFile + "destFile: " + destFile); File inputFile = new File(sourceFile); if (!inputFile.exists()) { return -1;// 找不到源文件, 则返回-1 } // 如果目标路径不存在, 则新建该路径 File outputFile = new File(destFile); if (outputFile.exists()){ return 0; } if (!outputFile.getParentFile().exists()) { outputFile.getParentFile().mkdirs(); } // 连接服务 OpenOfficeConnection connection = OpenOfficeServer.getConnection(); connection.connect(); // convert DocumentConverter converter = new OpenOfficeDocumentConverter(connection); if (isTxt(inputFile)) { File odtFile = isWindows(inputFile); converter.convert(odtFile, outputFile); } else { DocumentFormatRegistry factory = new BasicDocumentFormatRegistry(); DocumentFormat inputDocumentFormat = factory.getFormatByFileExtension(getExtensionName(inputFile.getAbsolutePath())); DocumentFormat outputDocumentFormat = factory.getFormatByFileExtension(getExtensionName(outputFile.getAbsolutePath())); converter.convert(inputFile, inputDocumentFormat, outputFile, outputDocumentFormat); } connection.disconnect(); return 0; } catch (ConnectException e) { log.error("openoffice 连接失败!",e); } catch (IOException e) { log.error("文件格式转换失败",e); } catch (InterruptedException e) { log.error("文件转换失败",e); return 1; } return 1; }
pdf-swf
import java.util.Properties;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import com.nuctech.common.util.CommandHelper;import com.nuctech.common.util.ConfigUtil;/** * pdf转swf类 */public class PdfToSwf { private static final Logger log = LoggerFactory.getLogger(PdfToSwf.class); /** * pdf转swf. * * @param pdfPath pdf路径 * @param swfPath swf路径 * @return result */ public static boolean pdfToSwf(String pdfPath, String swfPath) { String command = ""; Properties properies = ConfigUtil.getProperies(); if (System.getProperty("os.name").contains("Windows")) { command = properies.getProperty("windows.swftools.bin") + " -t " + pdfPath + " -o " + swfPath + " -f -s flashversion=9 "; } else { command = properies.getProperty("linux.swftools.bin") + " -t " + pdfPath + " -o " + swfPath + " -f -s flashversion=9 "; } log.debug("即将执行命令:" + command); return CommandHelper.runCommand(command) == 0; }}
注意: 启动openoffice方法 在 OpenOfficeServer的main方法里. application.server.properties 配置了两个软件的安装地址.
- freemarker生成world转PDF转SWF,加载到浏览器.解决最终浏览器加载的是xml代码的问题.
- 解决WebView加载URL跳转到系统浏览器的问题
- swf浏览器的缓存问题
- 解决浏览器安全沙箱问题的加载处理
- 解决IE浏览器,img的src加载图片问题
- IE11浏览器js加载数据不显示问题的解决
- 浏览器是怎么加载页面的
- 浏览器的加载过程
- 加载含有stage代码的swf
- WebView点击连接禁止跳到系统的浏览器及加载JS代码
- 解决ie浏览器对easyui加载时候弹出的div一闪而过的问题
- 加速浏览器的加载速度
- 浏览器加载网页的顺序
- 浏览器加载网页的过程
- 浏览器加载网页的顺序
- 浏览器怎么加载页面的?
- 浏览器的加载、解析、渲染
- IE和其它浏览器加载XML文档的方法
- TP框架简单网站统计功能的实现 PV IP UV
- 工作流调度器azkaban(以及各种工作流调度器比对)
- 为RecyclerView打造通用Adapter 让RecyclerView更加好用
- Java培训:课工场面试经验大放送
- 火狐之RESTClient插件安装-yellowcong
- freemarker生成world转PDF转SWF,加载到浏览器.解决最终浏览器加载的是xml代码的问题.
- Bootstrap
- 前端模型--PC端的2048
- sqoop数据迁移(基于Hadoop和关系数据库服务器之间传送数据)
- 非旋转treap模板(fhq treap)(洛谷3369,BZOJ3224)
- winSCP以预置密码进行验证
- 源码安装步骤详解
- python安装
- jdbc 实现ActiveRecord