Showing
1 changed file
with
66 additions
and
17 deletions
| @@ -2062,6 +2062,12 @@ body.exporting {{ | @@ -2062,6 +2062,12 @@ body.exporting {{ | ||
| 2062 | margin: 0; | 2062 | margin: 0; |
| 2063 | font-size: 1rem; | 2063 | font-size: 1rem; |
| 2064 | }} | 2064 | }} |
| 2065 | +.exporting *, | ||
| 2066 | +.exporting *::before, | ||
| 2067 | +.exporting *::after {{ | ||
| 2068 | + animation: none !important; | ||
| 2069 | + transition: none !important; | ||
| 2070 | +}} | ||
| 2065 | .export-progress {{ | 2071 | .export-progress {{ |
| 2066 | width: 220px; | 2072 | width: 220px; |
| 2067 | height: 6px; | 2073 | height: 6px; |
| @@ -2121,6 +2127,10 @@ ul, ol {{ | @@ -2121,6 +2127,10 @@ ul, ol {{ | ||
| 2121 | margin-left: 1.5em; | 2127 | margin-left: 1.5em; |
| 2122 | padding-left: 0; | 2128 | padding-left: 0; |
| 2123 | }} | 2129 | }} |
| 2130 | +img, canvas, svg {{ | ||
| 2131 | + max-width: 100%; | ||
| 2132 | + height: auto; | ||
| 2133 | +}} | ||
| 2124 | .meta-card {{ | 2134 | .meta-card {{ |
| 2125 | background: rgba(0,0,0,0.02); | 2135 | background: rgba(0,0,0,0.02); |
| 2126 | border-radius: 12px; | 2136 | border-radius: 12px; |
| @@ -2344,21 +2354,38 @@ pre.code-block {{ | @@ -2344,21 +2354,38 @@ pre.code-block {{ | ||
| 2344 | }} | 2354 | }} |
| 2345 | .chapter > *, | 2355 | .chapter > *, |
| 2346 | .hero-section, | 2356 | .hero-section, |
| 2347 | - .callout, | ||
| 2348 | - .chart-card, | ||
| 2349 | - .kpi-grid, | ||
| 2350 | - .table-wrap, | ||
| 2351 | - figure, | ||
| 2352 | - blockquote {{ | 2357 | +.callout, |
| 2358 | +.chart-card, | ||
| 2359 | +.kpi-grid, | ||
| 2360 | +.table-wrap, | ||
| 2361 | +figure, | ||
| 2362 | +blockquote {{ | ||
| 2353 | break-inside: avoid; | 2363 | break-inside: avoid; |
| 2354 | page-break-inside: avoid; | 2364 | page-break-inside: avoid; |
| 2355 | - }} | ||
| 2356 | - .chapter h2, | ||
| 2357 | - .chapter h3, | ||
| 2358 | - .chapter h4 {{ | 2365 | +}} |
| 2366 | +.chapter h2, | ||
| 2367 | +.chapter h3, | ||
| 2368 | +.chapter h4 {{ | ||
| 2359 | break-after: avoid; | 2369 | break-after: avoid; |
| 2360 | page-break-after: avoid; | 2370 | page-break-after: avoid; |
| 2361 | - }} | 2371 | + break-inside: avoid; |
| 2372 | +}} | ||
| 2373 | +.chart-card, | ||
| 2374 | +.table-wrap {{ | ||
| 2375 | + overflow: visible !important; | ||
| 2376 | +}} | ||
| 2377 | +.chart-card canvas {{ | ||
| 2378 | + width: 100% !important; | ||
| 2379 | + height: auto !important; | ||
| 2380 | +}} | ||
| 2381 | +.table-wrap table {{ | ||
| 2382 | + table-layout: fixed; | ||
| 2383 | + width: 100%; | ||
| 2384 | +}} | ||
| 2385 | +.table-wrap table th, | ||
| 2386 | +.table-wrap table td {{ | ||
| 2387 | + word-break: break-word; | ||
| 2388 | +}} | ||
| 2362 | }} | 2389 | }} |
| 2363 | """ | 2390 | """ |
| 2364 | 2391 | ||
| @@ -2821,6 +2848,7 @@ function exportPdf() { | @@ -2821,6 +2848,7 @@ function exportPdf() { | ||
| 2821 | exportBtn.disabled = true; | 2848 | exportBtn.disabled = true; |
| 2822 | } | 2849 | } |
| 2823 | showExportOverlay('正在导出PDF,请稍候...'); | 2850 | showExportOverlay('正在导出PDF,请稍候...'); |
| 2851 | + document.body.classList.add('exporting'); | ||
| 2824 | const pdf = new jspdf.jsPDF('p', 'mm', 'a4'); | 2852 | const pdf = new jspdf.jsPDF('p', 'mm', 'a4'); |
| 2825 | try { | 2853 | try { |
| 2826 | if (window.pdfFontData) { | 2854 | if (window.pdfFontData) { |
| @@ -2832,14 +2860,25 @@ function exportPdf() { | @@ -2832,14 +2860,25 @@ function exportPdf() { | ||
| 2832 | console.warn('Custom PDF font setup failed, fallback to default', err); | 2860 | console.warn('Custom PDF font setup failed, fallback to default', err); |
| 2833 | } | 2861 | } |
| 2834 | const pageWidth = pdf.internal.pageSize.getWidth(); | 2862 | const pageWidth = pdf.internal.pageSize.getWidth(); |
| 2835 | - const pxWidth = Math.max(target.scrollWidth, document.documentElement.scrollWidth); | 2863 | + const pxWidth = Math.max( |
| 2864 | + target.scrollWidth, | ||
| 2865 | + document.documentElement.scrollWidth, | ||
| 2866 | + Math.round(pageWidth * 3.78) | ||
| 2867 | + ); | ||
| 2836 | const restoreButton = () => { | 2868 | const restoreButton = () => { |
| 2837 | if (exportBtn) { | 2869 | if (exportBtn) { |
| 2838 | exportBtn.disabled = false; | 2870 | exportBtn.disabled = false; |
| 2839 | } | 2871 | } |
| 2872 | + document.body.classList.remove('exporting'); | ||
| 2840 | }; | 2873 | }; |
| 2841 | let renderTask; | 2874 | let renderTask; |
| 2842 | try { | 2875 | try { |
| 2876 | + // force charts to rerender at full width before capture | ||
| 2877 | + chartRegistry.forEach(chart => { | ||
| 2878 | + if (chart && typeof chart.resize === 'function') { | ||
| 2879 | + chart.resize(); | ||
| 2880 | + } | ||
| 2881 | + }); | ||
| 2843 | renderTask = pdf.html(target, { | 2882 | renderTask = pdf.html(target, { |
| 2844 | x: 8, | 2883 | x: 8, |
| 2845 | y: 12, | 2884 | y: 12, |
| @@ -2847,15 +2886,25 @@ function exportPdf() { | @@ -2847,15 +2886,25 @@ function exportPdf() { | ||
| 2847 | margin: [12, 12, 20, 12], | 2886 | margin: [12, 12, 20, 12], |
| 2848 | autoPaging: 'text', | 2887 | autoPaging: 'text', |
| 2849 | windowWidth: pxWidth, | 2888 | windowWidth: pxWidth, |
| 2850 | - pagebreak: { | ||
| 2851 | - mode: ['css', 'legacy'], | ||
| 2852 | - avoid: ['.chapter > *', '.callout', '.chart-card', '.table-wrap', '.kpi-grid', '.hero-section'] | ||
| 2853 | - }, | ||
| 2854 | html2canvas: { | 2889 | html2canvas: { |
| 2855 | - scale: 0.72, | 2890 | + scale: Math.min(1.2, Math.max(0.8, pageWidth / (target.clientWidth || pageWidth))), |
| 2856 | useCORS: true, | 2891 | useCORS: true, |
| 2892 | + scrollX: 0, | ||
| 2893 | + scrollY: -window.scrollY, | ||
| 2857 | logging: false | 2894 | logging: false |
| 2858 | }, | 2895 | }, |
| 2896 | + pagebreak: { | ||
| 2897 | + mode: ['css', 'legacy'], | ||
| 2898 | + avoid: [ | ||
| 2899 | + '.chapter > *', | ||
| 2900 | + '.callout', | ||
| 2901 | + '.chart-card', | ||
| 2902 | + '.table-wrap', | ||
| 2903 | + '.kpi-grid', | ||
| 2904 | + '.hero-section' | ||
| 2905 | + ], | ||
| 2906 | + before: '.chapter-divider' | ||
| 2907 | + }, | ||
| 2859 | callback: (doc) => doc.save('report.pdf') | 2908 | callback: (doc) => doc.save('report.pdf') |
| 2860 | }); | 2909 | }); |
| 2861 | } catch (err) { | 2910 | } catch (err) { |
-
Please register or login to post a comment