小工具知识网

当前位置: 首页 > 行业知识 > Java将富文本内容转为WORD,富文本内容中间附带图片(有核心代码)

行业知识

Java将富文本内容转为WORD,富文本内容中间附带图片(有核心代码)

2026-10-26 14:56:43 来源:互联网转载

天天被催要吧富文本的内容导出来,以前的做法就是标签一去,文本导出,现在不一样了正文,标题,图片都要不同的显示出来,最复杂的还是图片的处理,废话不多说开搞

()

主要使用的依赖

implementation 'org.jsoup:jsoup:1.+'    implementation 'org.apache.poi:poi-ooxml:5.2.+'

代码干货

1. 导出方法

    public ResponseEntity exportNews(Demo demo) {XWPFDocument document = new XWPFDocument();            // 设置页边距,数字单位厘米,自动换算            HTWConverter.pageMar(document,                    HTWConverter.pageMarConvert(2.8),                    HTWConverter.pageMarConvert(2.6),                    HTWConverter.pageMarConvert(3.7),                    HTWConverter.pageMarConvert(3.5));            XWPFParagraph timestampParagraph = document.createParagraph();            timestampParagraph.setAlignment(CENTER);            XWPFRun timestampRun = timestampParagraph.createRun();            timestampRun.setFontFamily("小标宋");            timestampRun.setFontSize(22);            timestampRun.setText(StringUtils.hasLength(demo.getTitle()) ? demo.getTitle() : "");            HTWConverter.processHtmlContent(document, demo.getContent());            String title = demo.getTitle();            if (StringUtils.hasLength(title)) {                int length = title.length();                title = length >= 11 ? title.substring(0, 10) : title;            } else {                title = "未命名新闻";            }            return Mono.just(ResponseEntity.ok().contentType(MediaType.APPLICATION_OCTET_STREAM)                    .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" +                            URLEncoder.encode(title + ".docx", StandardCharsets.UTF_8) + "\"")                    .body(HTWConverter.readDoc(document)));}

2. 核心工具

/** * HTW html to word * html富文本内容转word * * @author motcs * @since 2024-03-26 星期二 */@Log4j2@Servicepublic class HTWConverter {    /**     * 读取文档     *     * @param document 写好的文档     * @return 返回文档的字节码     */    public static byte[] readDoc(XWPFDocument document) {        try {            DefaultDataBuffer dataBuffer = new DefaultDataBufferFactory()                    .allocateBuffer(1024);            document.write(dataBuffer.asOutputStream());            return dataBuffer.asInputStream().readAllBytes();        } catch (IOException e) {            log.info("文档转换流失败,读取字节发生错误:{}", e.getMessage());            throw new RuntimeException("文档转换流失败,读取字节发生错误:" + e.getMessage());        }    }    /**     * 设置文档的页边距,单位为厘米是需要使用pageMarConvert 方法转换     * pageMarConvert(3.8)  转换的结果,等于实际文档的3.8厘米     *     * @param document 文档     * @param left     左边距     * @param right    右边距     * @param top      上边距     * @param bottom   下边距     */    public static void pageMar(XWPFDocument document, long left, long right, long top, long bottom) {        CTPageMar pageMar = document.getDocument().getBody().addNewSectPr().addNewPgMar();        pageMar.setLeft(BigInteger.valueOf(left));        pageMar.setRight(BigInteger.valueOf(right));        pageMar.setTop(BigInteger.valueOf(top));        pageMar.setBottom(BigInteger.valueOf(bottom));    }    /**     * 页边距单位换算,换算后单位厘米     *     * @param value 边距     * @return 返回换算后的数值     */    public static long pageMarConvert(double value) {        return (long) ((value / 2.54) * 1440);    }    /**     * 解析数据     *     * @param document    插入的文档     * @param htmlContent 需要解析的内容     */    public static void processHtmlContent(XWPFDocument document, String htmlContent) {        Document doc = Jsoup.parse(htmlContent);        Elements elements = doc.select("p, img, h1");        for (Element element : elements) {            if (element.tagName().equals("p")) {                addParagraphToDocument(document, element.text());            } else if (element.tagName().equals("img")) {                addImageToDocument(document, ImageUrl.builder().url(element.attr("src")).build());            } else if (element.tagName().equals("h1")) {                addParagraphH1ToDocument(document, element.text());            }        }    }    /**     * 插入正文,字体 仿宋GB2312 字号: 三号     *     * @param document 文档     * @param text     正文内容     */    public static void addParagraphToDocument(XWPFDocument document, String text) {        XWPFParagraph paragraph = document.createParagraph();        XWPFRun run = paragraph.createRun();        run.setText(text);        run.setFontSize(16);        run.setFontFamily("仿宋GB2312");        Double fontSizeAsDouble = run.getFontSizeAsDouble();        paragraph.setIndentationFirstLine(ObjectUtils.isEmpty(fontSizeAsDouble) ?                420 : fontSizeAsDouble.intValue() * 2 * 20);    }    /**     * 设置标题     *     * @param document 文档     * @param text     标题     */    public static void addParagraphH1ToDocument(XWPFDocument document, String text) {        XWPFParagraph paragraph = document.createParagraph();        XWPFRun run = paragraph.createRun();        run.setText(text);        run.setFontSize(16);        run.setFontFamily("黑体");    }    /**     * 文档增加图片     *     * @param document 文档     * @param image1   图片信息     */    public static void addImageToDocument(XWPFDocument document, ImageUrl image1) {        String imageUrl = image1.getUrl();        try {            BufferedImage image = ImageIO.read(new URL(imageUrl));            String fileExtension = imageUrl.substring(imageUrl.lastIndexOf('.') + 1);            log.info("图片后缀: {}", fileExtension);            ByteArrayOutputStream os = new ByteArrayOutputStream();            ImageIO.write(image, fileExtension, os);            try (InputStream is = new ByteArrayInputStream(os.toByteArray())) {                XWPFParagraph paragraph = document.createParagraph();                XWPFRun run = paragraph.createRun();                run.addPicture(is, PICTURE_TYPE_JPEG, "image." + fileExtension,                        (int) Math.rint(image1.getWidth() * Units.EMU_PER_CENTIMETER),                        (int) Math.rint(image1.getHeight() * Units.EMU_PER_CENTIMETER));            } catch (InvalidFormatException e) {                log.info("图片路径:{},解析失败:{}", imageUrl, e.getMessage());                addParagraphToDocument(document,"");                addParagraphToDocument(document, "解析图片失败!"+imageUrl);                addParagraphToDocument(document,"");            }        } catch (Exception e) {            log.info("下载图片失败:{}", e.getMessage());            addParagraphToDocument(document,"");            addParagraphToDocument(document, "下载图片失败!"+imageUrl);            addParagraphToDocument(document,"");        }    }}

3. 使用到的工具类

/** * @author motcs * @since 2024-03-26 星期二 */@Data@Builderpublic class ImageUrl implements Serializable {    /**     * 图片地址     */    private String url;    /**     * 图片宽度默认16.2     */    private double width;    /**     * 图片高度默认10.01     */    private double height;    public double getWidth() {        return width > 0 ? width : 16.2;    }    public double getHeight() {        return height > 0 ? height : 10.01;    }    }

好啦,到这里基本差不多了,样式那些就自己调整了。还可以有更多的扩展,这里仅仅只是做一个简单的示例。

()

上一篇:Android源码裁剪秘籍,定制系统,轻松上手!

下一篇:DNF外挂编程背后的法律风险与警示揭秘