问题描述:
最早试过了xml模板生成word,虽然文件格式保留的多,但是这种模板生成的word转html,用单纯的poi中的XWPFDocument、HWPFDocument是有问题的,因为word本质上还是xml,xml转html,poi是暂时不支持的,而且,除了上述的问题外,xml模板的语言很少有java去学习,一旦涉及到模板的调整,一般都是花费很大力气都很难改成功的,基于上述的情况,我并没有采用这种方法。
后来试过了zip中提取document.xml的形式,再将动态的xml最后压缩进zip源文件中,但是发现,维护成本加大,需要一个word和一个xml来进行维护,调整格式总是需要兼顾word模板,而且word转html还是有poi出现的问题,虽然可以生成docx格式的文件,但是还是无法应对需求
当然用Jacob也是可以的,不过因为Jacob的要求需要在windows系统上,所以只能pass掉
为了实现ftl转word和html,转化之后,在富文本中进行编辑修改,保存再次转化成word,实现文件的在线编辑和预览功能,采用了如下的操作方法
1、生成html模板
原始的word,通过文件->另存为
生成的文件为格式并不是utf-8,需要转码一下,这里直接用notepad++菜单栏中的Encoding直接转为utf-8编码即可
删除掉图片中绿色部分的xml代码,且修改<meta http-equiv=Content-Type content="text/html; charset=gb2312" >中的charset为utf-8,且文件名称后缀修改为.ftl格式
需要动态的内容可以将ftl的内容动态化,参考freemark的语法
2、springboot配置freemark解析
需要引入的jar:
<!-- freemarker -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
在application.properties文件中配置freemarker
#freemarker
spring.freemarker.template-loader-path=classpath:/templates/
spring.freemarker.charset=utf-8
spring.freemarker.cache=false
spring.freemarker.suffix=.ftl
项目如果启动不起来,可能是spring-boot-starter-freemarker中引入的jar出现了冲突,重复引入,需要排除重复的jar,需要注意
3、ftl生成html和word
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.StringWriter;
import java.util.Map;
import java.io.FileOutputStream;
import freemarker.template.Configuration;
import freemarker.template.Template;
import lombok.extern.slf4j.Slf4j;
import org.apachemons.lang.StringEscapeUtils;
import org.apache.poi.poifs.filesystem.DirectoryEntry;
import org.apache.poi.poifs.filesystem.DocumentEntry;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.springframework.web.util.HtmlUtils;
/**
* @FileNName: WordUtil
* @Description: word操作工具类
* @Author: guoxingliang
* @Create: 2019-08-16 17:08
* @Copyright: (c)2018年 ***公司
*/
@Slf4j
public class WordUtil {
private WordUtil() {}
/**
* @param content 页面内容
* @param filePath 文件生成的目标路径,例如:D:/wordFile/
* @param fileName 生成的文件名称,例如:test.doc
* @Desc:生成word文件
* @Author:guoxingliang
* @Date:2018-8-22下午05:33:42
*/
public static void createWord(String content, String filePath, String fileName) {
try {
//输出文件
File outFile = new File(filePath + File.separator + fileName);
//如果输出目标文件夹不存在,则创建
if (!outFile.getParentFile().exists()) {
outFile.getParentFile().mkdirs();
}
content = HtmlUtils.htmlUnescape(StringEscapeUtils.unescapeHtml(content));
//格式化html
byte[] by = content.getBytes();
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(by);
POIFSFileSystem poifsFileSystem = new POIFSFileSystem();
DirectoryEntry directory = poifsFileSystem.getRoot();
DocumentEntry documentEntry = directory.createDocument("WordDocument", byteArrayInputStream);
FileOutputStream fileOutputStream = new FileOutputStream(filePath + File.separator + fileName);
poifsFileSystem.writeFilesystem(fileOutputStream);
byteArrayInputStream.close();
fileOutputStream.close();
} catch (Exception e) {
log.error("word create fail, exception:", e);
}
}
/**
* @param dataMap word中需要展示的动态数据,用map集合来保存
* @param templateName word模板名称,例如:test.ftl
* @Desc:生成html文件
* @Author:guoxingliang
* @Date:2018-8-22下午05:33:42
*/
public static String createHtml(Map dataMap, String templateName) {
try {
//创建配置实例
Configuration configuration = new Configuration();
//设置编码
configuration.setDefaultEncoding("UTF-8");
//ftl模板文件统一放至 com.lun.template 包下面
configuration.setClassForTemplateLoading(WordUtil.class, "/templates");
//获取模板
Template template = configuration.getTemplate(templateName);
//将模板和数据模型合并生成文件
StringWriter stringWriter = new StringWriter();
//生成html
template.process(dataMap, stringWriter);
return stringWriter.toString();
} catch (Exception e) {
log.error("html create fail, exception:", e);
}
return null;
}
}
4、html字符串转码
由于html字符串中存在很多的特殊字符,比如说\t,\n,\r以及空格回车双引号,为了好处理,这里我进行了一些代码转化
加密:
HtmlConversionUtil.replaceBlank(StringEscapeUtils.escapeHtml(WordUtil.createHtml(dataMap, "agreementJurisdiction.ftl")));
解密:
StringEscapeUtils.unescapeHtml(htmlStr);
replaceBlank方法:
public static String replaceBlank(String str) {
String dest = "";
if (str!=null) {
Pattern p = Patternpile("\t|\r|\n");
Matcher m = p.matcher(str);
dest = m.replaceAll("");
}
return dest;
}
<!-- StringEscapeUtils所需要引入的依赖 -->
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.5</version>
</dependency>
注:上述方法虽然可以实现功能,但是暂未涉及到图片、页眉页脚等复杂格式的支持。
更多推荐
java关于ftl模板生成html以及word(实现在线预览、编辑功能)
发布评论