Java导出word两种方式(springBoot)

本文介绍了如何通过XML和FreeMarker技术,利用Java实现模块化设计,创建符合Office标准的Word文档,包括样式控制和内容管理,确保打印质量。步骤包括添加依赖、配置Freemarker和处理数据输出。
摘要由CSDN通过智能技术生成

最近项目要导出word报告,网上找了2天,总结了两种方式,因为习惯性的ctrl c +ctrl f,原文链接现在找不到了,请谅解。

因为我需要对模块进行设计排版,综合考虑用xml来做。

“用XML做就很简单了。Word从2003开始支持XML格式,大致的思路是先用office2003或者2007编辑好word的样式,然后另存为xml,将xml翻译为FreeMarker模板,最后用java来解析FreeMarker模板并输出Doc。经测试这样方式生成的word文档完全符合office标准,样式、内容控制非常便利,打印也不会变形,生成的文档和office中编辑文档完全一样。”

                                                                                                                摘自《java导出生成word

                                                                                https://www.cnblogs.com/lcngu/p/5247179.html

以下是结合我自己的项目编写的内容,核心逻辑代码可以直接使用,希望帮助到各位。

一.添加依赖

pom.xml文件增加以下依赖:

<!--word依赖-->
<dependency>
   <groupId>org.freemarker</groupId>
   <artifactId>freemarker</artifactId>
   <version>2.3.30</version>
</dependency>
<dependency>
   <groupId>dom4j</groupId>
   <artifactId>dom4j</artifactId>
   <version>1.6.1</version>
</dependency>
<dependency>
   <groupId>jaxen</groupId>
   <artifactId>jaxen</artifactId>
   <version>1.1.6</version>
</dependency>

二.实现方式

(一)不调用数据库,适合简单word样式:

结构 :WordController+WordService+WordServiceImpl+WordConfig+UserList(ftl)

代码:(import类和包我就不放了,idea提示导入吧)

WordController:

@Controller
@RequestMapping(value = "/word")
public class WordController {

    final static String TEST_WORD_FTL = "templates/*";  //设置word模板路径,一般存放在resources下的templates文件夹,如 templates/word.ftl
@Autowired
WordService wordService;

    //浏览器导出word(无对应mapper)
    @RequestMapping(value = "/createUserListWord", method = RequestMethod.GET)
    public ResponseEntity<Void> createUserListWord() {
        wordService.createUserListWord();
        return ResponseEntity.ok().build();
    }

}

WordService:

public interface WordService {
    void createUserListWord();
}

WordServiceImpl:

@Service
public class WordServiceImpl implements WordService {
    public void createUserListWord() {
        Map<?, ?> root = initData();  //数据源对象
        String template = "/template/test.ftl";  //模板文件的地址
        String path = "D:\\UserList.doc";  //生成的word文档的输出地址
        WordConfig.process(root, template, path);
    }

    private Map<?, ?> initData() {
        //数据处理
        Map<String, Object> root = new HashMap<String, Object>();

        List<User> users = new ArrayList<User>();
        User zhangsan = new User("张三", "123");
        User lisi = new User("李四", "456");
        User wangwu = new User("王五", "789");
        users.add(zhangsan);
        users.add(lisi);
        users.add(wangwu);

        root.put("users", users);
        root.put("title", "用户列表");

        return root;

    }

}

WordConfig:(freemarker核心实现)

/**
 * FreeMarker中生成word文档的核心函数
 *
 * @author WZC on 2021/8/9
 */
public final class WordConfig {
    private static Configuration configuration = null;

    private WordConfig() {
        throw new AssertionError();
    }

    /**
     * 根据模板生成相应的文件
     * @param root 保存数据的map
     * @param template 模板文件的地址
     * @param path 生成的word文档输出地址
     * @return
     */
    public static synchronized File process(Map<?, ?> root, String template, String path) {

        if (null == root ) {
            throw new RuntimeException("数据不能为空");
        }

        if (null == template) {
            throw new RuntimeException("模板文件不能为空");
        }

        if (null == path) {
            throw new RuntimeException("输出路径不能为空");
        }

        File file = new File(path);
        String templatePath = template.substring(0, template.lastIndexOf("/"));
        String templateName = template.substring(template.lastIndexOf("/") + 1, template.length());

        if (null == configuration) {
            configuration = new Configuration(Configuration.VERSION_2_3_23);  // 这里Configurantion对象不能有两个,否则多线程访问会报错
            configuration.setDefaultEncoding("utf-8");
            configuration.setClassicCompatible(true);
        }
        configuration.setClassForTemplateLoading(WordConfig.class, templatePath);

        Template t = null;
        try {
            t = configuration.getTemplate(templateName);
            Writer w = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "utf-8"));
            t.process(root, w);  // 这里w是一个输出地址,可以输出到任何位置,如控制台,网页等
            w.close();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return file;
    }

}

User:(实体类)

        

@Setter
@Getter
@AllArgsConstructor
public class User {

    private String username;
    private String password;

}

UserList.ftl:

讲一下过程,首先,创建空的word文档,编写模板:

 然后将word另存为xml文件,保存退出用Notepad++或其他xml编辑器打开,检查代码,名称是否正确,有时会出现user.name 被分开为 u   ser.name两段,只保留一个<w:t></w:t>标签。

找到<w:t>${user.username}</w:t>

 往上找到<w:tr>标签,在上面增加

<#list users as user> 需要遍历输出时添加,如果是固定格式也可以依次${}.

users是list的名字,user对应实体类名称。

 </w:tr>后别忘了加上</#list>

检查无误后,将xml文件改为ftl文件,UserList.ftl

 

复制文件到teample文件夹下,

 运行项目,打开浏览器输入http://localhost:15003/inspectManagement/word/createUserListWord

找到生成word目录D:\\UserList.doc,打开

以上为第一种简单的遍历方式 。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值