新增: HTML预览导出PDF并兼容Edge环境
- chromedp 通道新增源文件入口,file:// 加载原始HTML - 相对资源在原目录天然解析,printBackground 保背景色 - 预览工具栏新增导出按钮,默认文件名取当前HTML名 - 远程文件复用站点缓存路径,本地远程同一命令 - 浏览器探测扩Chrome+Edge双查,Markdown通道重复探测归一
This commit is contained in:
@@ -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) => {
|
||||
// 从编辑模式切换到预览模式
|
||||
|
||||
Reference in New Issue
Block a user