| | |
| | | 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) |
| | | } |
| | | } |
| | | } |
| | | //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) |
| | | // } |
| | | // } |
| | | //} |