feiyu02
2025-08-28 ddaa44400aa478058ffe9349d59904a130b7ce9c
src/main/kotlin/com/flightfeather/uav/common/file/Docx4jGenerator.kt
@@ -1,114 +1,114 @@
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)
//        }
//    }
//}