新增: HTML预览导出PDF并兼容Edge环境

- chromedp 通道新增源文件入口,file:// 加载原始HTML
- 相对资源在原目录天然解析,printBackground 保背景色
- 预览工具栏新增导出按钮,默认文件名取当前HTML名
- 远程文件复用站点缓存路径,本地远程同一命令
- 浏览器探测扩Chrome+Edge双查,Markdown通道重复探测归一
This commit is contained in:
lxy
2026-09-17 16:24:46 +08:00
parent 54b3f03d1f
commit e87ffe1d0c
4 changed files with 251 additions and 18 deletions
+9
View File
@@ -133,6 +133,15 @@ export function EnsureDrawioViewer(): $CancellablePromise<{ [_ in string]?: any
});
}
/**
* ExportHtmlFileToPDF 将HTML文件导出为PDF
*/
export function ExportHtmlFileToPDF(path: string, saveName: string): $CancellablePromise<{ [_ in string]?: any }> {
return $Call.ByID(3012957793, path, saveName).then(($result: any) => {
return $$createType2($result);
});
}
/**
* ExportPDF 导出PDF文件
*/
@@ -210,6 +210,17 @@
<template #icon><icon-save /></template>
</a-button>
</a-tooltip>
<!-- PDF 导出按钮(仅预览模式显示,后端 Chrome 渲染输出到桌面) -->
<a-tooltip v-if="!config.isEditMode" position="left" content="导出 PDF">
<a-button
type="outline"
size="small"
:loading="htmlExporting"
@click="handleExportHtmlPDF"
>
<template #icon><icon-file-pdf /></template>
</a-button>
</a-tooltip>
<!-- 预览/编辑切换按钮 -->
<a-tooltip
position="left"
@@ -440,6 +451,7 @@ import { previewExcel, previewWord, previewCsv } from '@/utils/filePreviewHandle
import { getFileCategory, isAudioFile } from '@/utils/fileTypeHelpers'
import { isDirty } from '../composables/useMultiPreview'
import { On, Off } from '@wailsio/events'
import { ExportHtmlFileToPDF } from '@bindings/u-desk/app'
import { connectionManager } from '@/api/connection-manager'
import { listDir, readFile } from '@/api/system'
import { resolveFileUrl, resolveFileUrlForProfile } from '../composables/useFilePreview'
@@ -528,32 +540,39 @@ const getFileTypeIcon = (filename: string): string => {
// HTML 预览 URL(OSS 需要先下载到本地再预览)
const htmlPreviewUrl = ref('')
// 导出 PDF 需要本地可访问的源文件路径:远程文件取缓存副本,本地文件即原路径
const htmlPreviewLocalPath = ref('')
watch(
() => [props.config.currentFileFullPath, props.config.isHtmlFile],
async ([path, isHtml]) => {
htmlPreviewUrl.value = ''
htmlPreviewLocalPath.value = ''
if (!path || !isHtml) return
// 下载到临时目录后是本地文件,统一用本地文件服务器
const base = getFileServerBaseURL()
const makeUrl = (localPath: string) => `${base}/localfs/html-preview?path=${encodeURIComponent(localPath)}`
const applyLocalPath = (localPath: string) => {
htmlPreviewLocalPath.value = localPath
htmlPreviewUrl.value = makeUrl(localPath)
}
if (connectionManager.isRemote()) {
try {
const transport = connectionManager.getTransport()
if (transport?.downloadSiteForPreview) {
const tempPath = await transport.downloadSiteForPreview(path)
htmlPreviewUrl.value = makeUrl(tempPath)
applyLocalPath(tempPath)
} else if (transport?.downloadForPreview) {
const tempPath = await transport.downloadForPreview(path)
htmlPreviewUrl.value = makeUrl(tempPath)
applyLocalPath(tempPath)
}
} catch (e) {
console.warn('[HTML预览] 下载失败:', path, e)
}
} else {
htmlPreviewUrl.value = makeUrl(path)
applyLocalPath(path)
}
},
{ immediate: true }
@@ -897,6 +916,31 @@ const handleExportCsvPDF = async () => {
)
}
// HTML 文件导出 PDF:交给后端 headless Chrome 渲染,绕开浏览器打印对话框
const htmlExporting = ref(false)
const handleExportHtmlPDF = async () => {
const srcPath = htmlPreviewLocalPath.value
if (!srcPath) {
Message.error('HTML 预览尚未就绪,请稍候重试')
return
}
const baseName = (props.config.currentFileName || 'export').replace(/\.[^.]+$/, '')
htmlExporting.value = true
try {
const res = await ExportHtmlFileToPDF(srcPath, baseName)
if (res?.success) {
Message.success(`PDF 已导出到: ${res.path}`)
} else {
Message.error(res?.message || 'PDF 导出失败')
}
} catch (e: any) {
// 后端约定的错误文案随异常抛出,无 Chrome 时向用户展示安装提示
Message.error(e?.message || 'PDF 导出失败')
} finally {
htmlExporting.value = false
}
}
// 监听模式切换,切换到预览模式时渲染 Mermaid 图表
watch(() => props.config.isEditMode, async (newVal, oldVal) => {
// 从编辑模式切换到预览模式