diff --git a/README.md b/README.md index 8691a304..91d4060a 100644 --- a/README.md +++ b/README.md @@ -22,11 +22,12 @@ npm run serve # 📚 功能列表 -### 通用功能 +### 基础功能 - 历史记录(撤销、重做) - 快捷键 - 右键菜单 -- 导出本地文件(PPTX、JSON、图片) +- 导出本地文件(PPTX、JSON、图片、PDF) +- 打印 ### 幻灯片页面编辑 - 页面添加、删除 - 页面顺序调整 diff --git a/src/utils/print.ts b/src/utils/print.ts new file mode 100644 index 00000000..1988a93d --- /dev/null +++ b/src/utils/print.ts @@ -0,0 +1,81 @@ +interface PageSize { + width: number; + height: number; + margin: number; +} + +const createIframe = () => { + const iframe = document.createElement('iframe') + iframe.style.width = '0' + iframe.style.height = '0' + iframe.style.position = 'absolute' + iframe.style.right = '0' + iframe.style.top = '0' + iframe.style.border = '0' + + document.body.appendChild(iframe) + + return iframe +} + +const writeContent = (doc: Document, printNode: HTMLElement, size: PageSize) => { + const docType = '' + + let style = '' + const styleSheets = document.styleSheets + if (styleSheets) { + for (const styleSheet of styleSheets) { + if (!styleSheet.cssRules) continue + + for (const rule of styleSheet.cssRules) { + style += rule.cssText + } + } + } + + const { width, height, margin } = size + const head = ` + + + + ` + const body = '' + printNode.innerHTML + '' + + doc.open() + doc.write(` + ${docType} + + ${head} + ${body} + + `) + doc.close() +} + +export const print = (printNode: HTMLElement, size: PageSize) => { + const iframe = createIframe() + const iframeContentWindow = iframe.contentWindow + + if (!iframe.contentDocument || !iframeContentWindow) return + writeContent(iframe.contentDocument, printNode, size) + + const handleLoadIframe = () => { + iframeContentWindow.focus() + iframeContentWindow.print() + document.body.removeChild(iframe) + } + + iframe.addEventListener('load', handleLoadIframe) +} \ No newline at end of file diff --git a/src/views/Editor/EditorHeader/ExportPDFDialog.vue b/src/views/Editor/EditorHeader/ExportPDFDialog.vue new file mode 100644 index 00000000..7062c3c7 --- /dev/null +++ b/src/views/Editor/EditorHeader/ExportPDFDialog.vue @@ -0,0 +1,165 @@ + + + + + \ No newline at end of file diff --git a/src/views/Editor/EditorHeader/index.vue b/src/views/Editor/EditorHeader/index.vue index 40a7f425..221d5389 100644 --- a/src/views/Editor/EditorHeader/index.vue +++ b/src/views/Editor/EditorHeader/index.vue @@ -8,6 +8,7 @@ 导出 JSON 导出 PPTX 导出图片 + 打印 / 导出 PDF @@ -76,6 +77,17 @@ + + + + @@ -91,12 +103,14 @@ import useExport from '@/hooks/useExport' import HotkeyDoc from './HotkeyDoc.vue' import ExportImgDialog from './ExportImgDialog.vue' +import ExportPDFDialog from './ExportPDFDialog.vue' export default defineComponent({ name: 'editor-header', components: { HotkeyDoc, ExportImgDialog, + ExportPDFDialog, }, setup() { const mainStore = useMainStore() @@ -117,6 +131,7 @@ export default defineComponent({ const hotkeyDrawerVisible = ref(false) const exportImgDialogVisible = ref(false) + const exportPDFDialogVisible = ref(false) const goIssues = () => { window.open('https://github.com/pipipi-pikachu/PPTist/issues') @@ -129,6 +144,7 @@ export default defineComponent({ showRuler, hotkeyDrawerVisible, exportImgDialogVisible, + exportPDFDialogVisible, exporting, enterScreening, enterScreeningFromStart,