Java實(shí)現(xiàn)將Markdown格式內(nèi)容轉(zhuǎn)換為Word文檔
一、引入必要的依賴
在開始之前,我們需要引入兩個(gè)關(guān)鍵的庫:一個(gè)是用于解析Markdown的markdown4j,另一個(gè)是用于生成Word文檔的Apache POI。這兩個(gè)庫將幫助我們完成從Markdown到Word的轉(zhuǎn)換過程。
<dependencies> <!-- Markdown解析庫 --> <dependency> <groupId>com.atlassian</groupId> <artifactId>markdown4j</artifactId> <version>2.3</version> </dependency> <!-- Word文檔生成庫 --> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>5.2.3</version> </dependency> </dependencies>
二、解析Markdown內(nèi)容
首先,我們需要將Markdown格式的內(nèi)容解析成普通的文本。這一步驟中,我們將使用Markdown4j庫來完成Markdown到HTML的轉(zhuǎn)換,然后再進(jìn)一步處理成純文本。
import com.atlassian.markdown.MarkdownProcessor; ???????public class MarkdownParser { public static String parseMarkdown(String markdownContent) { MarkdownProcessor markdownProcessor = new MarkdownProcessor(); return markdownProcessor.markdownToHtml(markdownContent); } }
三、將解析后的內(nèi)容寫入Word文檔
接下來,我們將使用Apache POI庫將解析后的內(nèi)容寫入到Word文檔中。這一步驟中,我們將創(chuàng)建一個(gè)XWPF文檔,并將解析后的內(nèi)容添加到文檔中。
import org.apache.poi.xwpf.usermodel.XWPFDocument; import org.apache.poi.xwpf.usermodel.XWPFParagraph; import org.apache.poi.xwpf.usermodel.XWPFRun; import java.io.FileOutputStream; import java.io.IOException; public class WordDocumentGenerator { public static void generateWordDocument(String content, String outputPath) throws IOException { XWPFDocument document = new XWPFDocument(); XWPFParagraph paragraph = document.createParagraph(); XWPFRun run = paragraph.createRun(); run.setText(content); try (FileOutputStream out = new FileOutputStream(outputPath)) { document.write(out); } document.close(); } }
四、完整的轉(zhuǎn)換流程
最后,我們將上述兩個(gè)步驟結(jié)合起來,實(shí)現(xiàn)一個(gè)完整的從Markdown到Word的轉(zhuǎn)換流程。這一步驟中,我們將讀取Markdown文件的內(nèi)容,解析后寫入到Word文檔中。
import java.io.FileReader; import java.io.IOException; import java.io.BufferedReader; public class MarkdownToWordConverter { public static void main(String[] args) { String markdownFilePath = "input.md"; String wordOutputPath = "output.docx"; try (BufferedReader reader = new BufferedReader(new FileReader(markdownFilePath))) { StringBuilder markdownContent = new StringBuilder(); String line; while ((line = reader.readLine()) != null) { markdownContent.append(line).append("\n"); } String parsedContent = MarkdownParser.parseMarkdown(markdownContent.toString()); WordDocumentGenerator.generateWordDocument(parsedContent, wordOutputPath); System.out.println("Markdown轉(zhuǎn)換為Word文檔成功!"); } catch (IOException e) { e.printStackTrace(); } } }
五、總結(jié)
通過上述步驟,我們成功地將Markdown格式的內(nèi)容轉(zhuǎn)換為了Word文檔。這一過程涉及到Markdown的解析和Word文檔的生成,展示了Java在文本處理和文檔生成方面的強(qiáng)大能力。希望這一指南能夠幫助你在實(shí)際開發(fā)中高效地完成類似任務(wù)。
六、方法補(bǔ)充
下面小編為大家整理了Java將Markdown格式轉(zhuǎn)Word的其他方法,希望對(duì)大家有所幫助
首先添加java處理的相關(guān)依賴:
<!-- excel工具 練習(xí)的項(xiàng)目自身的依賴--> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>4.1.2</version> </dependency> <!-- 新添加的依賴--> <!-- markdown格式轉(zhuǎn)換為html --> <dependency> <groupId>org.commonmark</groupId> <artifactId>commonmark</artifactId> <version>0.21.0</version> </dependency> <!-- poi-tl和poi-tl-plugin-markdown是處理markdown格式轉(zhuǎn)換為word格式,處理只處理markdown轉(zhuǎn)換為html,只需要commonnark依賴即可--> <dependency> <groupId>com.deepoove</groupId> <artifactId>poi-tl</artifactId> <version>1.10.1</version> </dependency> <dependency> <groupId>com.deepoove</groupId> <artifactId>poi-tl-plugin-markdown</artifactId> <version>1.0.3</version> </dependency>
編寫工具類
package com.xiaomifeng1010.common.utils; import com.deepoove.poi.XWPFTemplate; import com.deepoove.poi.config.Configure; import com.deepoove.poi.data.style.*; import com.deepoove.poi.plugin.markdown.MarkdownRenderData; import com.deepoove.poi.plugin.markdown.MarkdownRenderPolicy; import com.deepoove.poi.plugin.markdown.MarkdownStyle; import lombok.experimental.UtilityClass; import lombok.extern.slf4j.Slf4j; import org.apache.poi.xwpf.usermodel.XWPFTable; import org.apache.poi.xwpf.usermodel.XWPFTableCell; import org.commonmark.node.Node; import org.commonmark.parser.Parser; import org.commonmark.renderer.html.HtmlRenderer; import org.springframework.core.io.ClassPathResource; import javax.servlet.http.HttpServletResponse; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import java.util.HashMap; import java.util.Map; /** * @author xiaomifeng1010 * @version 1.0 * @date: 2024-08-24 17:23 * @Description */ @UtilityClass @Slf4j public class MarkdownUtil { /** * markdown轉(zhuǎn)html * * @param markdownContent * @return */ public String markdownToHtml(String markdownContent) { Parser parser = Parser.builder().build(); Node document = parser.parse(markdownContent); HtmlRenderer renderer = HtmlRenderer.builder().build(); String htmlContent = renderer.render(document); log.info(htmlContent); return htmlContent; } /** * 將markdown格式內(nèi)容轉(zhuǎn)換為word并保存在本地 * * @param markdownContent * @param outputFileName */ public void toDoc(String markdownContent, String outputFileName) { log.info("markdownContent:{}", markdownContent); MarkdownRenderData code = new MarkdownRenderData(); code.setMarkdown(markdownContent); MarkdownStyle style = MarkdownStyle.newStyle(); style = setMarkdownStyle(style); code.setStyle(style); // markdown樣式處理與word模板中的標(biāo)簽{{md}}綁定 Map<String, Object> data = new HashMap<>(); data.put("md", code); Configure config = Configure.builder().bind("md", new MarkdownRenderPolicy()).build(); try { // 獲取classpath String path = MarkdownUtil.class.getClassLoader().getResource("").getPath(); log.info("classpath:{}", path); //由于部署到linux上后,程序是從jar包中去讀取resources下的文件的,所以需要使用流的方式讀取,所以獲取流,而不是直接使用文件路徑 // 所以可以這樣獲取 InputStream resourceAsStream = MarkdownUtil.class.getClassLoader().getResourceAsStream(""); // 建議使用spring的工具類來獲取,如下 ClassPathResource resource = new ClassPathResource("markdown" + File.separator + "markdown_template.docx"); InputStream resourceAsStream = resource.getInputStream(); XWPFTemplate.compile(resourceAsStream, config) .render(data) .writeToFile(path + "out_markdown_" + outputFileName + ".docx"); } catch (IOException e) { log.error("保存為word出錯(cuò)"); } } /** * 將markdown轉(zhuǎn)換為word文檔并下載 * * @param markdownContent * @param response * @param fileName */ public void convertAndDownloadWordDocument(String markdownContent, HttpServletResponse response, String fileName) { log.info("markdownContent:{}", markdownContent); MarkdownRenderData code = new MarkdownRenderData(); code.setMarkdown(markdownContent); MarkdownStyle style = MarkdownStyle.newStyle(); style = setMarkdownStyle(style); code.setStyle(style); // markdown樣式處理與word模板中的標(biāo)簽{{md}}綁定 Map<String, Object> data = new HashMap<>(); data.put("md", code); Configure configure = Configure.builder().bind("md", new MarkdownRenderPolicy()).build(); try { fileName=URLEncoder.encode(fileName, StandardCharsets.UTF_8.name()); //由于部署到linux上后,程序是從jar包中去讀取resources下的文件的,所以需要使用流的方式讀取,所以獲取流,而不是直接使用文件路徑 // 所以可以這樣獲取 InputStream resourceAsStream = MarkdownUtil.class.getClassLoader().getResourceAsStream(""); // 建議使用spring的工具類來獲取,如下 ClassPathResource resource = new ClassPathResource("markdown" + File.separator + "markdown_template.docx"); InputStream resourceAsStream = resource.getInputStream(); response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(fileName, "UTF-8") + ".docx"); // contentType不設(shè)置也是也可以的,可以正常解析到 response.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document;charset=utf-8"); XWPFTemplate template = XWPFTemplate.compile(resourceAsStream, configure) .render(data); template.writeAndClose(response.getOutputStream()); } catch (IOException e) { log.error("下載word文檔失敗:{}", e.getMessage()); } } /** * 設(shè)置轉(zhuǎn)換為word文檔時(shí)的基本樣式 * @param style * @return */ public MarkdownStyle setMarkdownStyle(MarkdownStyle style) { // 一定設(shè)置為false,不然生成的word文檔中各元素前邊都會(huì)加上有層級(jí)效果的一串?dāng)?shù)字, // 比如一級(jí)標(biāo)題 前邊出現(xiàn)1 二級(jí)標(biāo)題出現(xiàn)1.1 三級(jí)標(biāo)題出現(xiàn)1.1.1這樣的數(shù)字 style.setShowHeaderNumber(false); // 修改默認(rèn)的表格樣式 // table header style(表格頭部,通常為表格頂部第一行,用于設(shè)置列標(biāo)題) RowStyle headerStyle = new RowStyle(); CellStyle cellStyle = new CellStyle(); // 設(shè)置表格頭部的背景色為灰色 cellStyle.setBackgroundColor("cccccc"); Style textStyle = new Style(); // 設(shè)置表格頭部的文字顏色為黑色 textStyle.setColor("000000"); // 頭部文字加粗 textStyle.setBold(true); // 設(shè)置表格頭部文字大小為12 textStyle.setFontSize(12); // 設(shè)置表格頭部文字垂直居中 cellStyle.setVertAlign(XWPFTableCell.XWPFVertAlign.CENTER); cellStyle.setDefaultParagraphStyle(ParagraphStyle.builder().withDefaultTextStyle(textStyle).build()); headerStyle.setDefaultCellStyle(cellStyle); style.setTableHeaderStyle(headerStyle); // table border style(表格邊框樣式) BorderStyle borderStyle = new BorderStyle(); // 設(shè)置表格邊框顏色為黑色 borderStyle.setColor("000000"); // 設(shè)置表格邊框?qū)挾葹?px borderStyle.setSize(3); // 設(shè)置表格邊框樣式為實(shí)線 borderStyle.setType(XWPFTable.XWPFBorderType.SINGLE); style.setTableBorderStyle(borderStyle); // 設(shè)置普通的引用文本樣式 ParagraphStyle quoteStyle = new ParagraphStyle(); // 設(shè)置段落樣式 quoteStyle.setSpacingBeforeLines(0.5d); quoteStyle.setSpacingAfterLines(0.5d); // 設(shè)置段落的文本樣式 Style quoteTextStyle = new Style(); quoteTextStyle.setColor("000000"); quoteTextStyle.setFontSize(8); quoteTextStyle.setItalic(true); quoteStyle.setDefaultTextStyle(quoteTextStyle); style.setQuoteStyle(quoteStyle); return style; } public static void main(String[] args) { String markdownContent = "# 一級(jí)標(biāo)題\n" + "## 二級(jí)標(biāo)題\n" + "### 三級(jí)標(biāo)題\n" + "#### 四級(jí)標(biāo)題\n" + "##### 五級(jí)標(biāo)題\n" + "###### 六級(jí)標(biāo)題\n" + "## 段落\n" + "這是一段普通的段落。\n" + "## 列表\n" + "### 無序列表\n" + "- 項(xiàng)目1\n" + "- 項(xiàng)目2\n" + "- 項(xiàng)目3\n" + "### 有序列表\n" + "1. 項(xiàng)目1\n" + "2. 項(xiàng)目2\n" + "3. 項(xiàng)目3\n" + "## 鏈接\n" + "[百度](https://www.baidu.com)\n" + "## 圖片\n" + "\n" + "## 表格\n" + "| 表頭1 | 表頭2 | 表頭3 |\n" + "|-------|-------|-------|\n" + "| 單元格1 | 單元格2 | 單元格3 |\n" + "| 單元格4 | 單元格5 | 單元格6 |"; toDoc(markdownContent, "test23"); } }
到此這篇關(guān)于Java實(shí)現(xiàn)將Markdown格式內(nèi)容轉(zhuǎn)換為Word文檔的文章就介紹到這了,更多相關(guān)Java Markdown轉(zhuǎn)Word內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
在springboot中使用AOP進(jìn)行全局日志記錄
這篇文章主要介紹就在springboot中使用AOP進(jìn)行全局日志記錄,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-11-11SSM spring Bean基礎(chǔ)配置實(shí)例詳解
Bean是Spring框架中的一個(gè)基本單元,通常是一個(gè)普通的Java對(duì)象(POJO),但它被Spring容器管理,本文給大家介紹SSM spring Bean基礎(chǔ)配置,感興趣的朋友一起看看吧2025-06-06聊聊Springboot2.x的session和cookie有效期
這篇文章主要介紹了Springboot2.x的session和cookie有效期,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-09-09drools規(guī)則動(dòng)態(tài)化實(shí)踐解析
這篇文章主要為大家介紹了drools規(guī)則動(dòng)態(tài)化實(shí)踐解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-02-02springboot2.0以上調(diào)度器配置線程池的實(shí)現(xiàn)
這篇文章主要介紹了springboot2.0以上調(diào)度器配置線程池的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-12-12使用@ControllerAdvice同時(shí)配置過濾多個(gè)包
這篇文章主要介紹了使用@ControllerAdvice同時(shí)配置過濾多個(gè)包的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-06-06Java多線程通信wait()和notify()代碼實(shí)例
這篇文章主要介紹了Java多線程通信wait()和notify()代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-04-04