导出功能
GanttFlow 支持将甘特图导出为 PNG、PDF 和 Excel 格式,方便生成报告和分享。
导出 PNG
tsx
import React, { useRef } from "react"
import { EnhancedGanttChart } from "@agions/gantt-flow"
function App() {
const ganttRef = useRef(null)
const exportPNG = async () => {
try {
const dataUrl = await ganttRef.current?.exportAsPNG()
console.log("PNG 导出成功:", dataUrl)
// 创建下载链接
const link = document.createElement("a")
link.href = dataUrl
link.download = `gantt-${Date.now()}.png`
link.click()
} catch (error) {
console.error("导出失败:", error)
}
}
return (
<>
<button onClick={exportPNG}>导出 PNG</button>
<EnhancedGanttChart ref={ganttRef} tasks={tasks} />
</>
)
}导出 PDF
tsx
const exportPDF = async () => {
try {
const blob = await ganttRef.current?.exportAsPDF()
// 创建下载链接
const url = URL.createObjectURL(blob)
const link = document.createElement("a")
link.href = url
link.download = `gantt-${Date.now()}.pdf`
link.click()
// 清理
URL.revokeObjectURL(url)
} catch (error) {
console.error("导出失败:", error)
}
}导出 Excel
tsx
const exportExcel = async () => {
try {
const blob = await ganttRef.current?.exportAsExcel()
const url = URL.createObjectURL(blob)
const link = document.createElement("a")
link.href = url
link.download = `gantt-${Date.now()}.xlsx`
link.click()
URL.revokeObjectURL(url)
} catch (error) {
console.error("导出失败:", error)
}
}导出选项
可以自定义导出效果:
typescript
interface ExportOptions {
/** 背景颜色(默认白色) */
backgroundColor?: string
/** 内边距(像素) */
padding?: number
/** 图片清晰度 (1-3),默认 2 */
scale?: number
/** 图片质量 (0-1),默认 1 */
quality?: number
/** 导出格式 */
format?: 'png' | 'jpeg' | 'pdf'
/** 文件名前缀 */
filename?: string
/** 是否包含表头 */
includeHeader?: boolean
/** 是否包含图例 */
includeLegend?: boolean
/** 是否包含今日线 */
includeTodayLine?: boolean
/** 是否包含网格线 */
includeGridLines?: boolean
/** Excel 特定:是否包含依赖关系 */
includeDependencies?: boolean
/** Excel 特定:是否包含进度 */
includeProgress?: boolean
/** Excel 特定:日期格式 */
dateFormat?: string
}使用示例
tsx
const options: ExportOptions = {
backgroundColor: "#ffffff",
padding: 40,
scale: 2,
quality: 1,
format: "png",
filename: "project-gantt",
includeHeader: true,
includeLegend: true,
includeTodayLine: true
}
await ganttRef.current?.exportAsPNG(options)
await ganttRef.current?.exportAsPDF(options)导出面板 UI
GanttFlow 内置了导出面板组件:
tsx
import { ExportPanel } from "@agions/gantt-flow"
<EnhancedGanttChart tasks={tasks}>
<ExportPanel
position="top-right"
showFormats={["png", "pdf", "excel"]}
buttonText="导出"
dropdownStyle={{ zIndex: 100 }}
/>
</EnhancedGanttChart>ExportPanel Props
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
position | 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left' | 'top-right' | 位置 |
showFormats | ('png' | 'pdf' | 'excel')[] | ['png', 'pdf', 'excel'] | 显示的格式 |
buttonText | string | '导出' | 按钮文字 |
options | ExportOptions | {} | 导出选项 |
工具栏示例
tsx
import React, { useRef } from "react"
import { EnhancedGanttChart } from "@agions/gantt-flow"
import "@agions/gantt-flow/style"
function ProjectGantt() {
const ganttRef = useRef(null)
const handleExport = async (format: 'png' | 'pdf' | 'excel') => {
const options = {
backgroundColor: "#ffffff",
scale: 2,
filename: `gantt-${format}`
}
try {
switch (format) {
case 'png':
const pngData = await ganttRef.current?.exportAsPNG(options)
downloadFile(pngData, `${options.filename}.png`)
break
case 'pdf':
const pdfBlob = await ganttRef.current?.exportAsPDF(options)
downloadBlob(pdfBlob, `${options.filename}.pdf`)
break
case 'excel':
const excelBlob = await ganttRef.current?.exportAsExcel({
includeDependencies: true,
includeProgress: true
})
downloadBlob(excelBlob, `${options.filename}.xlsx`)
break
}
} catch (error) {
console.error('导出失败:', error)
alert('导出失败,请重试')
}
}
const downloadFile = (dataUrl: string, filename: string) => {
const link = document.createElement('a')
link.href = dataUrl
link.download = filename
link.click()
}
const downloadBlob = (blob: Blob, filename: string) => {
const url = URL.createObjectURL(blob)
const link = document.createElement('a')
link.href = url
link.download = filename
link.click()
URL.revokeObjectURL(url)
}
return (
<div className="gantt-container">
{/* 工具栏 */}
<div className="toolbar">
<h2>项目甘特图</h2>
<div className="toolbar-actions">
<button onClick={() => ganttRef.current?.fitToScreen()}>
适应屏幕
</button>
<button onClick={() => handleExport('png')}>
📷 PNG
</button>
<button onClick={() => handleExport('pdf')}>
📄 PDF
</button>
<button onClick={() => handleExport('excel')}>
📊 Excel
</button>
</div>
</div>
{/* 甘特图 */}
<div style={{ height: "calc(100vh - 120px)" }}>
<EnhancedGanttChart ref={ganttRef} tasks={tasks} />
</div>
</div>
)
}导出样式优化
暗色主题导出
tsx
// 临时切换到亮色主题再导出
const exportWithLightTheme = async () => {
// 切换到亮色
ganttRef.current?.setTheme('light')
// 等待渲染完成
await new Promise(resolve => setTimeout(resolve, 100))
// 导出
const dataUrl = await ganttRef.current?.exportAsPNG({
backgroundColor: '#ffffff'
})
// 恢复原主题
ganttRef.current?.setTheme('dark')
downloadFile(dataUrl, 'gantt-light.png')
}自定义水印
tsx
const exportWithWatermark = async () => {
const dataUrl = await ganttRef.current?.exportAsPNG()
// 使用 canvas 添加水印
const img = new Image()
img.onload = () => {
const canvas = document.createElement('canvas')
canvas.width = img.width
canvas.height = img.height
const ctx = canvas.getContext('2d')
ctx?.drawImage(img, 0, 0)
// 添加水印
ctx!.font = '24px Arial'
ctx!.fillStyle = 'rgba(0, 0, 0, 0.2)'
ctx!.fillText('GanttFlow', img.width - 120, img.height - 20)
// 下载
const watermarkedUrl = canvas.toDataURL('image/png')
downloadFile(watermarkedUrl, 'gantt-watermarked.png')
}
img.src = dataUrl
}注意事项
WARNING
- 异步操作:导出是异步的,确保在导出完成后再进行其他操作
- 大数据量:任务数量很多时,导出可能需要几秒钟
- 跨域问题:如果图片包含跨域资源,需要配置 CORS
- 内存占用:高清晰度导出会占用较多内存,注意设备性能