diff --git a/bun.lockb b/bun.lockb index 2faf4dc..ff01caf 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/package.json b/package.json index 7fd08f5..8cf16a1 100644 --- a/package.json +++ b/package.json @@ -45,6 +45,7 @@ "@electron-toolkit/preload": "^3.0.1", "@electron-toolkit/utils": "^3.0.0", "antd": "^5.21.1", + "html-docx-js-typescript": "^0.1.5", "katex": "^0.16.11", "marked": "^14.1.2", "marked-katex-extension": "^5.1.2", diff --git a/src/main/index.ts b/src/main/index.ts index 51cc647..58cefb0 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -7,6 +7,7 @@ import path from 'node:path' import { mdToHtml } from '../../lib/render' import { getTheme } from '../../lib/utils' import { embedImageIntoHtml } from './utils' +import { asBlob } from 'html-docx-js-typescript' function createWindow(): void { // Create the browser window. @@ -158,6 +159,44 @@ app.whenReady().then(() => { return true } ) + ipcMain.handle( + 'createDocx', + async ( + _, + markdown: string, + themeName: string = 'aps', + filepath: string, + filename: string + ): Promise => { + const { response } = await dialog.showMessageBox({ + type: 'warning', + title: '导出 Word', + message: + '导出的 DOCX 文件可能存在部分样式丢失,请手动调整或或选择导出为 PDF 文件. 是否继续?', + buttons: ['取消', '继续'] + }) + if (response === 0) { + return false + } + const { filePath, canceled } = await dialog.showSaveDialog({ + title: '导出论文', + filters: [{ name: 'Word 文件', extensions: ['docx'] }], + defaultPath: filename.split('.')[0] + '.docx', + showsTagField: false, + properties: ['createDirectory'] + }) + if (canceled) { + return false + } + const theme = getTheme(themeName) + const dist = path.resolve(filePath) + const html = await embedImageIntoHtml(await mdToHtml(markdown, theme), filepath) + const docx = await asBlob(html) + const docxBuffer = Buffer.from(docx instanceof Blob ? await docx.arrayBuffer() : docx) + await fs.writeFile(dist, docxBuffer) + return true + } + ) createWindow() diff --git a/src/preload/index.d.ts b/src/preload/index.d.ts index 04cb184..5e00688 100644 --- a/src/preload/index.d.ts +++ b/src/preload/index.d.ts @@ -16,6 +16,12 @@ declare global { filepath: string, filename: string ) => Promise + createDocx: ( + markdown: string, + themeName: string, + filepath: string, + filename: string + ) => Promise } } } diff --git a/src/preload/index.ts b/src/preload/index.ts index dff9d4b..4e2e0b0 100644 --- a/src/preload/index.ts +++ b/src/preload/index.ts @@ -28,6 +28,14 @@ const api = { filename: string ): Promise => { return electronAPI.ipcRenderer.invoke('createPdf', markdown, themeName, filepath, filename) + }, + createDocx: ( + markdown: string, + themeName: string, + filepath: string, + filename: string + ): Promise => { + return electronAPI.ipcRenderer.invoke('createDocx', markdown, themeName, filepath, filename) } } diff --git a/src/renderer/index.html b/src/renderer/index.html index a9b6b9e..c659b7d 100644 --- a/src/renderer/index.html +++ b/src/renderer/index.html @@ -2,7 +2,7 @@ - EasyPaper v1.5.0 + EasyPaper v1.6.0 HTML +

论文格式: