FreeMaker + xml 导出word(处理目录,图片和页眉页脚问题)

本文介绍了如何使用FreeMarker模板和XML来导出Word文档,重点关注处理目录、图片和页眉页脚的技术细节。通过模板中的变量替换,实现了动态数据填充。此外,文章提供了Java代码示例,展示了如何通过ActiveXComponent操作Word应用刷新目录,并讲解了图片的Base64编码和动态名称替换,以及页眉页脚的设置方法。
摘要由CSDN通过智能技术生成

 

FreeMaker + xml 导出word

 

 

首先介绍几种java导出word方案 

 

1JacobJava-COM Bridge的缩写,它在Java与微软的COM组件之间构建一座桥梁。使用Jacob自带的DLL动态链接库,并通过JNI的方式实现了在Java平台上对COM程序的调用。DLL动态链接库的生成需要windows平台的支持。

 

 

 

2 Apache POI包括一系列的API,它们可以操作基于MicroSoft OLE 2 Compound Document Format的各种格式文件,可以通过这些APIJava中读写ExcelWord等文件。他的excel处理很强大,对于word还局限于读取,目前只能实现一些简单文件的操作,不能设置样式。

 

 

 

3 Java2word是一个在java程序中调用 MS Office Word 文档的组件(类库)。该组件提供了一组简单的接口,以便java程序调用他的服务操作Word 文档。
这些服务包括: 打开文档、新建文档、查找文字、替换文字,插入文字、插入图片、插入表格,在书签处插入文字、插入图片、插入表格等。填充数据到表格中读取表格数据 ,1.1版增强的功能: 指定文本样式,指定表格样式。如此,则可动态排版word文档。

 

 

 

4 iText操作Excel还行。对于复杂的大量的word也是噩梦。用法很简单但是功能很少不能设置打印方向等问题。

 

 

 

5 JSP输出样式基本不达标,而且要打印出来就更是惨不忍睹。

 

 

 

6、 用XML做就很简单了。Word2003开始支持XML格式,大致的思路是先用office2003或者2007编辑好word的样式,然后另存为xml,将xml翻译为FreeMarker模板,最后用java来解析FreeMarker模板并输出Doc。经测试这样方式生成的word文档完全符合office标准,样式、内容控制非常便利,打印也不会变形,生成的文档和office中编辑文档完全一样。

 

 

 

看过方案后就知道了 第 6 种方案效果好点,下面我们就举个例子介绍下这个方案

 

首先要制作模板 模板里的需要传入的数据用${data} 填充,在代码里给其赋值即可

 

模板制作好后 ,点击另存为  xml  文件  如:data.xml

 

如果xml需要动态填充  可以用

 

<!-- 循环开始 -->
<#list personnelView as e>

 

</#list>

 

<!-- 循环结束 -->

 

<!-- 循环开始 -->
<#list personnelView as e>  // personnelView
为循环集合
<w:tr wsp:rsidR="001E023B" wsp:rsidTr="004E45BD">
<w:tblPrEx>
<w:tblCellMar>
<w:top w:w="0" w:type="dxa"/>
<w:bottom w:w="0" w:type="dxa"/>
</w:tblCellMar>
</w:tblPrEx>
<w:trPr>
<w:trHeight w:val="405"/>
</w:trPr>
<w:tc>
<w:tcPr>
<w:tcW w:w="1920" w:type="dxa"/>
<w:vAlign w:val="center"/>
</w:tcPr>
<w:p wsp:rsidR="001E023B" wsp:rsidRDefault="001D2E3B" wsp:rsidP="004E45BD">
<w:pPr>
<w:jc w:val="center"/>
</w:pPr>
<w:r>
<w:rPr>
<w:rFonts w:hint="fareast"/>
</w:rPr>
<w:t>${e_index +1}</w:t> //e_index 为索引从0 开始
</w:r>
</w:p>
</w:tc>
<w:tc>
<w:tcPr>
<w:tcW w:w="1083" w:type="dxa"/>
<w:vAlign w:val="center"/>
</w:tcPr>
<w:p wsp:rsidR="001E023B" wsp:rsidRDefault="001D2E3B" wsp:rsidP="004E45BD">
<w:r>
<w:rPr>
<w:rFonts w:hint="fareast"/>
</w:rPr>
<w:t>${e.COLUMN_1}</w:t>
</w:r>
</w:p>
</w:tc>
<w:tc>
<w:tcPr>
<w:tcW w:w="1142" w:type="dxa"/>
<w:gridSpan w:val="3"/>
</w:tcPr>
<w:p wsp:rsidR="001E023B" wsp:rsidRDefault="001D2E3B" wsp:rsidP="004E45BD">
<w:pPr>
<w:rPr>
<w:rFonts w:hint="fareast"/>
</w:rPr>
</w:pPr>
<w:r>
<w:rPr>
<w:rFonts w:hint="fareast"/>
</w:rPr>
<w:t>${e.COLUMN_2}</w:t>
</w:r>
</w:p>
</w:tc>
<w:tc>
<w:tcPr>
<w:tcW w:w="1578" w:type="dxa"/>
<w:gridSpan w:val="3"/>
<w:vAlign w:val="center"/>
</w:tcPr>
<w:p wsp:rsidR="001E023B" wsp:rsidRDefault="001D2E3B" wsp:rsidP="004E45BD">
<w:r>
<w:rPr>
<w:rFonts w:hint="fareast"/>
</w:rPr>
<w:t>${e.COLUMN_3}</w:t>
</w:r>
</w:p>
</w:tc>
<w:tc>
<w:tcPr>
<w:tcW w:w="1168" w:type="dxa"/>
<w:gridSpan w:val="2"/>
<w:vAlign w:val="center"/>
</w:tcPr>
<w:p wsp:rsidR="001E023B" wsp:rsidRDefault="001D2E3B" wsp:rsidP="004E45BD">
<w:r>
<w:rPr>
<w:rFonts w:hint="fareast"/>
</w:rPr>
<w:t>${e.COLUMN_4}</w:t>
</w:r>
</w:p>
</w:tc>
<w:tc>
<w:tcPr>
<w:tcW w:w="2181" w:type="dxa"/>
<w:gridSpan w:val="3"/>
<w:vAlign w:val="center"/>
</w:tcPr>
<w:p wsp:rsidR="001E023B" wsp:rsidRDefault="001D2E3B" wsp:rsidP="004E45BD">
<w:r>
<w:rPr>
<w:rFonts w:hint="fareast"/>
</w:rPr>
<w:t>${e.COLUMN_5}</w:t>
</w:r>
</w:p>
</w:tc>
</w:tr>
</#list>
<!--
循环结束 -->

 

二、详细介绍

 

1、以上呢都是我看别人的东西复制过来的其实都一样FreeMaker 最主要的一个特点就是整理模板数据替换用${data};data就是你的数据

 

那在java中保存的数据时用map来存放数据

 

如:Map<String, Object> root = new HashMap<String, Object>();

 

如现在要保存一个实体user

 

User的对象有idnamesexmenun(菜单)picstr(头像)这些属性

 

User userObj=new User();

 

在保存的时候只要将数据库中的数据封装到user中然后通过root.put(“user”, userObj);

 

在模板相应的位置中代替这些值如名称:${user.name},性别${user.sex}

 

当遇到对象有子集的时候也就是用户有几个菜单时可以使用<#list user.menun as m>在这个中间又可以得到自己想要的东西如${m.menunName}</#list>当然这个是循环的对于它循环的索引直接使用变量名+下划线index即可如:${m_index};

 

2、这些东西估计大家都会现在说说插入目录问题

 

因为目录需要内容创建完成之后才能刷新目录所以在此处我寻求好多方法不知道怎么使用最后我折中想了个办法就是在xml转为word完成之后我另存一份word;在另存之前我先刷新目录这样就把目录问题解决了;废话少说例子上:

 

public void xmlToWord(String docfile, String htmlfile) {

 

       ActiveXComponent app =null;

 

       try {

 

           app=new ActiveXComponent("Word.Application"); // 启动word

 

           app.setProperty("Visible", new Variant(false));

 

           Dispatch docs = app.getProperty("Documents").toDispatch();

 

          

 

          

 

           Dispatch doc = Dispatch.invoke(

 

                  docs,

 

                  "Open",

 

                  Dispatch.Method,

 

                  new Object[] { docfile, new Variant(false),

 

                         new Variant(true) }, new

您可以使用Apache POI库和iText库来将Freemarker生成的Word文档转换为PDF。首先,您需要使用Freemarker生成Word文档,然后使用Apache POI库将其加载到内存中。接下来,您可以使用iText库将加载的Word文档转换为PDF格式。以下是一个示例代码片段,演示如何执行此操作: ```java import freemarker.template.Configuration; import freemarker.template.Template; import org.apache.poi.xwpf.usermodel.XWPFDocument; import org.apache.poi.xwpf.usermodel.XWPFParagraph; import org.apache.poi.xwpf.usermodel.XWPFRun; import org.apache.poi.xwpf.usermodel.XWPFTable; import org.apache.poi.xwpf.usermodel.XWPFTableCell; import org.apache.poi.xwpf.usermodel.XWPFTableRow; import java.io.*; import java.util.HashMap; import java.util.List; import java.util.Map; public class WordToPdfConverter { public static void main(String[] args) { try { // Load the Freemarker template Configuration configuration = new Configuration(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS); configuration.setClassForTemplateLoading(WordToPdfConverter.class, "/"); Template template = configuration.getTemplate("template.ftl"); // Prepare data for the template Map<String, Object> data = new HashMap<>(); data.put("name", "John Doe"); // ... add more data // Generate the Word document using Freemarker Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("output.docx"))); template.process(data, out); out.close(); // Convert the Word document to PDF using Apache POI and iText FileInputStream in = new FileInputStream(new File("output.docx")); XWPFDocument document = new XWPFDocument(in); File outputFile = new File("output.pdf"); FileOutputStream outStream = new FileOutputStream(outputFile); PdfOptions options = PdfOptions.create(); PdfConverter.getInstance().convert(document, outStream, options); // Clean up outStream.close(); in.close(); System.out.println("Word document converted to PDF successfully!"); } catch (Exception e) { e.printStackTrace(); } } } ``` 请确保在运行代码之前将`template.ftl`替换为您自己的Freemarker模板文件。此外,您需要在项目中添加Apache POI和iText库的依赖项。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值