HTML转Word JAVA工具类,简单样式可导出,

1 引入jar包 包括以下几个jar包 

<dependency>
	<groupId>org.docx4j</groupId>
	<artifactId>docx4j-core</artifactId>
	<version>8.3.2</version>
</dependency>
<dependency>
	<groupId>org.docx4j</groupId>
	<artifactId>docx4j-ImportXHTML</artifactId>
	<version>8.3.11</version>
</dependency>
<dependency>
	<groupId>org.apache.poi</groupId>
	<artifactId>poi-ooxml</artifactId>
	<version>5.2.3</version>
</dependency>
<dependency>
	<groupId>org.jsoup</groupId>
	<artifactId>jsoup</artifactId>
	<version>1.15.3</version>
</dependency>
<dependency>
	<groupId>net.sf.jtidy</groupId>
	<artifactId>jtidy</artifactId>
	<version> r938</version>
</dependency>

2. 工具类转化  html 转化成word

大坑 html和word 一些编码规则 不同 如 空格 &nbsp

import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.tidy.Tidy;

import javax.servlet.http.HttpServletResponse;
import java.io.*;

@Slf4j
public class FileUtil {

	private static final Logger LOGGER = LoggerFactory.getLogger(FileUtil.class);

	private final static String wordPath = "src/main/resources/export/word/";

	public static void exportWord(String htmlContent, HttpServletResponse response) throws IOException {
		log.info("开始导出word",htmlContent);
		HtmlToDocxConverter.convertHtmlToDocxAndWriteToResponse(htmlContent, response,wordPath);
		LOGGER.info("导出word成功");
	}
	public static String cleanHtml(String html) {
		// 清理 html
		Tidy tidy = new Tidy();
		tidy.setXHTML(true); // 输出 XHTML
		tidy.setInputEncoding("UTF-8");
		tidy.setOutputEncoding("UTF-8");

		StringReader reader = new StringReader(html);
		StringWriter writer = new StringWriter();

		tidy.parse(reader, writer);
		// 转移
		String exprotContent = writer.toString()
				.replace("&amp;", "&")
				.replace("&lt;", "<")
				.replace("&gt;", ">")
				.replace("&quot;", "\"")
				.replace("&#39;", "'")
				.replace("&nbsp;", "\u00A0");
		return exprotContent;
	}
}

3html 转word转化器

import org.docx4j.convert.in.xhtml.XHTMLImporterImpl;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.openpackaging.parts.WordprocessingML.MainDocumentPart;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.UUID;

public class HtmlToDocxConverter {

    /**
     * 将 HTML 文本转换为 DOCX 文件并写入 HTTP 响应流中。
     *
     * @param htmlContent HTML 文本内容
     * @param response    HTTP 响应对象
     * @param cacheDir    文件缓存目录
     */
    public static void convertHtmlToDocxAndWriteToResponse(String htmlContent, HttpServletResponse response, String cacheDir) {
        try {
            // 创建 WordMLPackage 对象
            WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.createPackage();
            MainDocumentPart documentPart = wordMLPackage.getMainDocumentPart();

            // 使用 XHTMLImporterImpl 进行转换
            XHTMLImporterImpl htmlImporter = new XHTMLImporterImpl(wordMLPackage);
            documentPart.getContent().addAll(htmlImporter.convert(htmlContent, null));

            // 生成临时文件路径
            Path cachePath = Paths.get(cacheDir);
            if (!Files.exists(cachePath)) {
                Files.createDirectories(cachePath);
            }
            String tempFileName = UUID.randomUUID().toString() + ".docx";
            Path tempFilePath = cachePath.resolve(tempFileName);

            // 保存文件
            wordMLPackage.save(tempFilePath.toFile());

            // 设置响应头
            response.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document");
            response.setHeader("Content-Disposition", "attachment; filename=converted_file.docx");

            // 将文件内容写入响应流
            try (FileInputStream fis = new FileInputStream(tempFilePath.toFile());
                 OutputStream os = response.getOutputStream()) {
                byte[] buffer = new byte[4096];
                int bytesRead;
                while ((bytesRead = fis.read(buffer)) != -1) {
                    os.write(buffer, 0, bytesRead);
                }
            }
            // 删除临时文件
            Files.delete(tempFilePath);

        } catch (Exception e) {
            e.printStackTrace();
            // 处理异常,例如返回错误信息
            response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            try {
                response.getWriter().write("Error converting HTML to DOCX: " + e.getMessage());
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }
}

4 controller直接导出 


  public void exportHrSpeak(@RequestBody TCompetitionHrSpeakParams params, HttpServletResponse response) {
//        TCompetitionHrSpeakDto tCompetitionHrSpeak = iTCompetitionHrSpeakService.exportWord(params).getData();
        String content = params.getContent();
        log.info("导出 竞聘  讲稿 params:" + params);
        // 转义 加格式校验。
        String s = FileUtil.cleanHtml(content);
        log.info("导出 竞聘  讲稿 清理完 之后 :" + s);
        try {
            FileUtil.exportWord(s, response);
        } catch (IOException e) {
            log.info("导出 竞聘  讲稿 异常 e:" + e.getMessage());
        }
    }

5 html内容 

<html><p style="text-align: center;"><span style="font-size: 24pt;"><strong>竞聘述职口述环节讲稿</strong></span></p>
<p style="text-align: left;"><span style="font-size: 14pt;"><span style="font-size: 12pt;">尊敬的各位评委、各位领导,大家好!</span></span></p>
<p style="text-align: left; padding-left: 40px;"><span style="font-size: 14pt;"><span style="font-size: 12pt;">欢迎大家参与今天的<strong><span style="color: #0000ff;">风扇外销销</span></strong>竞聘</span></span></p>
<p style="text-align: left; padding-left: 40px;"><span style="font-size: 14pt;"><span style="font-size: 12pt;">在正式开始之前请大家将手机调为静音或振动模式</span></span></p>
<p style="text-align: left; padding-left: 40px;">本次竞聘流程分为人力口述-PPT述职-评委提问三个环节</p>
<p style="text-align: left; padding-left: 40px;">下面由我对大家的口碑、业绩、政府案测试结果进行口述</p>
<p style="text-align: left; padding-left: 40px;">第一位AA,第二位BB,请做好准备</p>
<p style="text-align: left; padding-left: 40px;">姓名:AA</p>
<p style="text-align: left; padding-left: 40px;">司龄:80年,工龄:80年</p>
<p style="text-align: left; padding-left: 40px;">口碑:80</p>
<p style="text-align: left; padding-left: 40px;">政府案测试:达标</p>
<p style="text-align: left; padding-left: 40px;">业绩:KP1100潜能/历能模型:合格</p>
<p style="text-align: left; padding-left: 40px;">优点:全是优点</p>
<p style="text-align: left; padding-left: 40px;">缺点:没有缺点</p>
<p style="text-align: left; padding-left: 40px;">接下来开始PPT述职,时间为7分钟,6分钟响铃一次,7分钟响铃二次,超时一票否决</p>
<p></p>
<p style="text-align: left; padding-left: 40px;">第二位BB</p>
<p style="text-align: left; padding-left: 40px;">姓名:BB</p>
<p style="text-align: left; padding-left: 40px;">司龄:80年,工龄:80年</p>
<p style="text-align: left; padding-left: 40px;">口碑:80</p>
<p style="text-align: left; padding-left: 40px;">政府案测试:达标</p>
<p style="text-align: left; padding-left: 40px;">业绩:KP1100潜能/历能模型:合格</p>
<p style="text-align: left; padding-left: 40px;">优点:全是优点</p>
<p style="text-align: left; padding-left: 40px;">缺点:没有缺点</p>
<p style="text-align: left; padding-left: 40px;">接下来开始PPT述职,时间为7分钟,6分钟响铃一次,7分钟响铃二次,超时一票否决</p>
<p style="text-align: left; padding-left: 40px;"></p>
<p style="text-align: left; padding-left: 40px;">没有第三位了</p></html>

前端界面

导出文档样式 ,

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值