package com.flightfeather.uav.common.file
|
|
import freemarker.template.Configuration
|
import freemarker.template.Template
|
|
import org.docx4j.openpackaging.packages.WordprocessingMLPackage
|
import org.docx4j.openpackaging.parts.WordprocessingML.MainDocumentPart
|
import java.io.ByteArrayInputStream
|
import java.io.ByteArrayOutputStream
|
import java.io.File
|
import java.io.OutputStreamWriter
|
import java.nio.charset.StandardCharsets
|
|
/**
|
* Word文件生成器(基于Docx4j + FreeMarker)
|
* @date 2025/8/28 09:29
|
* @author feiyu
|
*/
|
class Docx4jGenerator(
|
private val templatePath: String,
|
private val freemarkerConfig: Configuration = defaultFreemarkerConfig()
|
) {
|
private var wordMLPackage: WordprocessingMLPackage? = null
|
private var mainDocumentPart: MainDocumentPart? = null
|
|
/**
|
* 创建Word文档包
|
*/
|
fun loadTemplate(): Docx4jGenerator {
|
wordMLPackage = WordprocessingMLPackage.createPackage()
|
mainDocumentPart = wordMLPackage?.mainDocumentPart
|
|
return this
|
}
|
|
/**
|
* 使用FreeMarker填充模板数据
|
*/
|
fun fillData(dataModel: Map<String, Any>): Docx4jGenerator {
|
val template = freemarkerConfig.getTemplate(templatePath.substringAfterLast("/"))
|
val xmlContent = renderTemplate(template, dataModel)
|
|
mainDocumentPart?.unmarshal(ByteArrayInputStream(xmlContent.toByteArray(StandardCharsets.UTF_8)))
|
return this
|
}
|
|
/**
|
* 添加图片到Word文档
|
* @param imagePath 图片路径
|
* @param width 宽度(像素)
|
* @param height 高度(像素)
|
* @param paragraphId 段落ID,指定图片插入位置
|
*/
|
fun addImage(imagePath: String, width: Int, height: Int, paragraphId: String): Docx4jGenerator {
|
// 实现图片添加逻辑
|
return this
|
}
|
|
/**
|
* 添加表格到Word文档
|
* @param data 表格数据
|
* @param paragraphId 段落ID,指定表格插入位置
|
*/
|
fun addTable(data: List<List<String>>, paragraphId: String): Docx4jGenerator {
|
// 实现表格添加逻辑
|
return this
|
}
|
|
/**
|
* 保存生成的Word文件
|
* @param outputPath 输出文件路径
|
*/
|
fun save(outputPath: String) {
|
wordMLPackage?.save(File(outputPath))
|
}
|
|
/**
|
* 使用FreeMarker渲染模板
|
*/
|
private fun renderTemplate(template: Template, dataModel: Map<String, Any>): String {
|
val outputStream = ByteArrayOutputStream()
|
val writer = OutputStreamWriter(outputStream, StandardCharsets.UTF_8)
|
template.process(dataModel, writer)
|
writer.flush()
|
return outputStream.toString(StandardCharsets.UTF_8.name())
|
}
|
|
companion object {
|
/**
|
* 默认FreeMarker配置
|
*/
|
fun defaultFreemarkerConfig(): Configuration {
|
val config = Configuration(Configuration.VERSION_2_3_31)
|
config.defaultEncoding = "UTF-8"
|
config.setClassForTemplateLoading(Docx4jGenerator::class.java, "/templates")
|
return config
|
}
|
|
/**
|
* 简化调用的静态方法
|
*/
|
fun generate(
|
templatePath: String,
|
outputPath: String,
|
dataModel: Map<String, Any>,
|
config: Configuration = defaultFreemarkerConfig()
|
) {
|
Docx4jGenerator(templatePath, config)
|
.loadTemplate()
|
.fillData(dataModel)
|
.save(outputPath)
|
}
|
}
|
}
|