freemarker根据模板生成html,并在显示在页面富文本(tinymce)框中,编辑后,下载为pdf文件
1、新建word文档,编辑内容,动态数据用占位符替换。
2、文件另存为.html文件,并放到项目中,改后缀为.ftl。
文件中要去掉前面<xml></xml>中的内容
3、生成html方法
String content = new FreeMarkerModalUtil().createModalHtml(map,"agreementHtmlSim.ftl",fileName);
/**
* 生成html.
* @return String
* @throws IOException
*/
public String createModalHtml(Map<String, Object> dataMap, String templateName, String fileName) throws IOException, TemplateException {
//注入模板
configuration.setClassForTemplateLoading(this.getClass(), "/templates");
Template template = null;
try {
template = configuration.getTemplate(templateName);
} catch (IOException e) {
e.printStackTrace();
}
//将模板和数据模型合并生成文件
StringWriter stringWriter = new StringWriter();
//生成html
template.process(dataMap, stringWriter);
return replaceBlank(stringWriter.toString());
}
public String replaceBlank(String str) {
String dest = "";
if (str!=null) {
Pattern p = Pattern.compile("\t|\r|\n");
Matcher m = p.matcher(str);
dest = m.replaceAll("");
}
return dest;
}
4、vue 集成 tinymce富文本编辑器
<template>
<a-card shadow>
<a-form :form="form" @submit="handleSubmit" ref="editorModel" :model="editorModel">
<a-form-item prop="content">
<a-textarea class="tinymce-textarea" id="tinymceEditer" style="height: 800px">
</a-textarea>
</a-form-item>
</a-form>
</a-card>
</template>
<script>
import axios from 'axios'
import tinymce from 'tinymce/tinymce'
import 'tinymce/themes/silver'
import 'tinymce/plugins/image'// 插入上传图片插件
import 'tinymce/plugins/table'// 插入表格插件
import 'tinymce/plugins/lists'// 列表插件
import 'tinymce/plugins/wordcount'// 字数统计插件
import 'tinymce/plugins/fullpage'
import 'tinymce/plugins/visualblocks'
import 'tinymce/plugins/advlist'
import 'tinymce/plugins/textpattern'
import 'tinymce/plugins/autolink'
import 'tinymce/plugins/charmap'
import 'tinymce/plugins/print'
import 'tinymce/plugins/preview'
import 'tinymce/plugins/hr'
import 'tinymce/plugins/anchor'
import 'tinymce/plugins/pagebreak'
import 'tinymce/plugins/textcolor'
import 'tinymce/plugins/paste'
import 'tinymce/plugins/imagetools'
import 'tinymce/plugins/importcss'
import 'tinymce/plugins/searchreplace'
import 'tinymce/plugins/insertdatetime'
import 'tinymce/plugins/nonbreaking'
import 'tinymce/plugins/noneditable'
import 'tinymce/plugins/visualchars'
import 'tinymce/plugins/save'
import 'tinymce/plugins/directionality'
import 'tinymce/plugins/colorpicker'
import 'tinymce/plugins/codesample'
import 'tinymce/plugins/contextmenu'
import 'tinymce/icons/default'
export default {
name: 'CreateWord',
components: { },
props: ['propsData'],
data () {
return {
form: this.$form.createForm(this),
pageData: null,
editorModel: {
content: '',
fileName: ''
},
customEditor: null
};
},
mounted () {
this.init()
},
methods: {
init () {
this.$nextTick(() => {
const vm = this
const height = document.body.offsetHeight
tinymce.init({
selector: '#tinymceEditer',
language_url: '/tinymce/langs/zh_CN.js',
language: 'zh_CN',
skin_url: '/tinymce/skins/ui/oxide',
height: height,
branding: false,
elementpath: false,
powerpaste_word_import: 'merge', // 是否保留word粘贴样式 clean | merge
images_upload_credentials: true, //可选
paste_data_images: true, //可拖拽圖片
menubar: 'edit insert format table tools',
plugins: [
'advlist autolink lists image charmap print preview hr anchor pagebreak imagetools',
'searchreplace visualblocks visualchars fullpage',
'insertdatetime nonbreaking save table contextmenu directionality',
'paste textcolor colorpicker textpattern imagetools'
],
toolbar1: 'newnote print preview | undo redo | insert | styleselect | forecolor backcolor bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent |image',
autosave_interval: '20s',
image_advtab: true,
table_default_styles: {
width: '100%',
height: '100%',
borderCollapse: 'collapse'
},
images_upload_handler: (blobInfo, success, failure) => {
const img = 'data:image/jpeg;base64,' + blobInfo.base64()
success(img)
},
setup: function (editor) {
editor.on('init', function (e) {
});
editor.on('keydown', function (e) {
localStorage.editorContent = tinymce.get('tinymceEditer').getContent();
vm.editorModel.content = tinymce.get('tinymceEditer').getContent();
});
editor.on('keyup', function (e) {
localStorage.editorContent = tinymce.get('tinymceEditer').getContent();
vm.editorModel.content = tinymce.get('tinymceEditer').getContent();
});
}
});
});
},
destroyed () {
tinymce.get('tinymceEditer').destroy();
}
}
</script>
this.customEditor = response.data.content
tinymce.get('tinymceEditer').setContent(this.customEditor);
可根据自己需要导入插件。把skin和langs复制到public下
5、html转换成pdf
public class PdfHelper {
public static ITextRenderer getRender() throws IOException, DocumentException {
ITextRenderer render = new ITextRenderer();
ITextFontResolver fontResolver = render.getFontResolver();
fontResolver.addFont("C:/Windows/Fonts/simsun.ttc", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
fontResolver.addFont("C:/Windows/Fonts/arial.ttf", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
return render;
}
/**
* 根据html 生成pdf 输出流
* @param htmlContent
* @param outputStream
* @return
* @throws Exception
*/
public static OutputStream generatePdfByHtml(String htmlContent, OutputStream outputStream) throws Exception{
ITextRenderer render = PdfHelper.getRender();
//htmlContent = htmlContent.replaceAll(" "," ");
render.setDocumentFromString(htmlContent);
render.layout();
render.createPDF(outputStream);
render.finishPDF();
return outputStream;
}
pdf文件中显示中文,需要设置fontResolver.addFont("C:/Windows/Fonts/simsun.ttc", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED); ,simsun.ttc为宋体。
同时把ftl文件中的“宋体”全部替换为SimSun。
6、最终下载的pdf文件