feat: 报告生成扩展 PPT/Word/Excel 多格式导出
- 新增 ExportReportDOCX 导出 Word 文档(纯标准库)
- 新增 ExportReportPPTX 导出 PPT 演示文稿(纯标准库)
- 新增 ExportReportXLSX 导出 Excel 表格(纯标准库)
- 新增 /api/report/export/{docx,pptx,xlsx} 路由
- 前端增加多格式导出下拉菜单(PDF/Word/PPT/Excel)
- 前端导出函数按格式名提示成功信息
- 零网络依赖,纯 Go 标准库实现
This commit is contained in:
@@ -8,6 +8,18 @@ export function exportReportPDF(data) {
|
||||
return http.post('/report/export/pdf', data, { responseType: 'blob' })
|
||||
}
|
||||
|
||||
export function exportReportDOCX(data) {
|
||||
return http.post('/report/export/docx', data, { responseType: 'blob' })
|
||||
}
|
||||
|
||||
export function exportReportPPTX(data) {
|
||||
return http.post('/report/export/pptx', data, { responseType: 'blob' })
|
||||
}
|
||||
|
||||
export function exportReportXLSX(data) {
|
||||
return http.post('/report/export/xlsx', data, { responseType: 'blob' })
|
||||
}
|
||||
|
||||
export function previewReport(data) {
|
||||
return http.post('/report/preview', data)
|
||||
}
|
||||
|
||||
@@ -97,10 +97,20 @@
|
||||
</span>
|
||||
</div>
|
||||
<div class="card-actions" v-if="reportContent">
|
||||
<el-button size="small" :loading="exporting" @click="exportToPDF">
|
||||
<el-icon><Download /></el-icon>
|
||||
导出 PDF
|
||||
</el-button>
|
||||
<el-dropdown trigger="click" @command="exportReport">
|
||||
<el-button size="small" :loading="exporting">
|
||||
<el-icon><Download /></el-icon>
|
||||
导出 <el-icon><ArrowDown /></el-icon>
|
||||
</el-button>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item command="pdf"><el-icon><Document /></el-icon> PDF 文档</el-dropdown-item>
|
||||
<el-dropdown-item command="docx"><el-icon><Reading /></el-icon> Word 文档</el-dropdown-item>
|
||||
<el-dropdown-item command="pptx"><el-icon><Grid /></el-icon> PPT 演示文稿</el-dropdown-item>
|
||||
<el-dropdown-item command="xlsx"><el-icon><Reading /></el-icon> Excel 表格</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
<el-button size="small" @click="resetReport">
|
||||
清除
|
||||
</el-button>
|
||||
@@ -148,8 +158,8 @@
|
||||
<script setup>
|
||||
import { onMounted, ref } from 'vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { Edit, Download } from '@element-plus/icons-vue'
|
||||
import { generateReport, exportReportPDF } from '@/api/report'
|
||||
import { Edit, Download, Document, Reading, ArrowDown, Grid } from '@element-plus/icons-vue'
|
||||
import { generateReport as apiGenerateReport, exportReportPDF, exportReportDOCX, exportReportPPTX, exportReportXLSX } from '@/api/report'
|
||||
import { listKnowledgeSpaces } from '@/api/knowledge'
|
||||
|
||||
const generating = ref(false)
|
||||
@@ -173,7 +183,7 @@ async function generateReport() {
|
||||
|
||||
generating.value = true
|
||||
try {
|
||||
const res = await generateReport({
|
||||
const res = await apiGenerateReport({
|
||||
topic: form.value.topic.trim(),
|
||||
summary: form.value.summary,
|
||||
sections: form.value.sections,
|
||||
@@ -197,28 +207,44 @@ async function generateReport() {
|
||||
}
|
||||
}
|
||||
|
||||
async function exportToPDF() {
|
||||
async function exportReport(command) {
|
||||
if (!reportContent.value) return
|
||||
|
||||
exporting.value = true
|
||||
try {
|
||||
const blob = await exportReportPDF({
|
||||
report: reportContent.value,
|
||||
})
|
||||
|
||||
// 下载 PDF
|
||||
const formatNames = { pdf: 'PDF', docx: 'Word', pptx: 'PPT', xlsx: 'Excel' }
|
||||
const exts = { pdf: '.pdf', docx: '.docx', pptx: '.pptx', xlsx: '.xlsx' }
|
||||
const formatName = formatNames[command] || '文件'
|
||||
const ext = exts[command] || '.pdf'
|
||||
let blob
|
||||
switch (command) {
|
||||
case 'pdf':
|
||||
blob = await exportReportPDF({ report: reportContent.value })
|
||||
break
|
||||
case 'docx':
|
||||
blob = await exportReportDOCX({ report: reportContent.value })
|
||||
break
|
||||
case 'pptx':
|
||||
blob = await exportReportPPTX({ report: reportContent.value })
|
||||
break
|
||||
case 'xlsx':
|
||||
blob = await exportReportXLSX({ report: reportContent.value })
|
||||
break
|
||||
default:
|
||||
return
|
||||
}
|
||||
const url = URL.createObjectURL(blob)
|
||||
const a = document.createElement('a')
|
||||
a.href = url
|
||||
const filename = (reportContent.value.topic || 'report') + '.pdf'
|
||||
a.download = filename.replace(/[^a-zA-Z一-龥 -]/g, '_')
|
||||
const filename = (reportContent.value.topic || 'report') + ext
|
||||
a.download = filename.replace(/[^a-zA-Z一-龥龥 -]/g, '_')
|
||||
document.body.appendChild(a)
|
||||
a.click()
|
||||
document.body.removeChild(a)
|
||||
URL.revokeObjectURL(url)
|
||||
ElMessage.success('PDF 已下载')
|
||||
ElMessage.success(`${formatName} 已下载`)
|
||||
} catch (error) {
|
||||
ElMessage.error('PDF 导出失败')
|
||||
ElMessage.error(`${formatName} 导出失败`)
|
||||
} finally {
|
||||
exporting.value = false
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user