Skip to content

Commit b611533

Browse files
committed
Enhance Excel to PDF conversion with chart rendering and rectangle/line support
- Updated ExcelToPdfConverter to handle charts in addition to images and rows. - Added logic to render charts as visual elements on PDF pages, including overflow handling for right-anchored charts. - Introduced PdfRectBlock and PdfLineBlock records to represent filled rectangles and line segments on PDF pages. - Implemented methods in PdfPage to add rectangles and lines, ensuring they are drawn in the correct order during PDF writing. - Modified PdfWriter to output rectangle and line data to the PDF format. - Updated README image update script to reflect changes in the number of test cases.
1 parent de32dc3 commit b611533

259 files changed

Lines changed: 6788 additions & 1252 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

PdfPage.cs

Whitespace-only changes.

README.md

Lines changed: 250 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -56,19 +56,19 @@ byte[] pdfBytes = MiniPdf.ConvertToPdf(stream);
5656

5757
## Benchmark
5858

59-
MiniPdf output is compared against LibreOffice as the reference renderer across **90 classic test cases** (including 30 image-embedding cases).
59+
MiniPdf output is compared against LibreOffice as the reference renderer across **120 classic test cases** (including 30 image-embedding cases and 30 chart cases).
6060

6161
| Category | Count | Threshold |
6262
|---|---|---|
63-
| 🟢 Excellent | 82 | ≥ 90% |
64-
| 🟡 Acceptable | 7 | 70% – 90% |
65-
| 🔴 Needs Improvement | 1 | < 70% |
63+
| 🟢 Excellent | 97 | ≥ 90% |
64+
| 🟡 Acceptable | 21 | 70% – 90% |
65+
| 🔴 Needs Improvement | 2 | < 70% |
6666

67-
**Average overall score: 96.4%** (text similarity 40% + visual similarity 40% + page count 20%)
67+
**Average overall score: 94.7%** (text similarity 40% + visual similarity 40% + page count 20%)
6868

6969
### Visual Comparison
7070

71-
All 90 test cases comparing MiniPdf output vs LibreOffice reference. Page 1 shown for multi-page results.
71+
All test cases comparing MiniPdf output vs LibreOffice reference. Page 1 shown for multi-page results.
7272

7373
<table>
7474
<tr><th>MiniPdf</th><th>LibreOffice (Reference)</th></tr>
@@ -792,11 +792,255 @@ All 90 test cases comparing MiniPdf output vs LibreOffice reference. Page 1 show
792792
<td><img src="tests/MiniPdf.Benchmark/reports/images/classic90_project_status_with_milestones_p1_minipdf.png" width="320"/></td>
793793
<td><img src="tests/MiniPdf.Benchmark/reports/images/classic90_project_status_with_milestones_p1_reference.png" width="320"/></td>
794794
</tr>
795+
<tr>
796+
<td><b>classic91</b></td>
797+
<td>Simple bar chart 🟢 96.7%</td>
798+
</tr>
799+
<tr>
800+
<td><img src="tests/MiniPdf.Benchmark/reports/images/classic91_simple_bar_chart_p1_minipdf.png" width="320"/></td>
801+
<td><img src="tests/MiniPdf.Benchmark/reports/images/classic91_simple_bar_chart_p1_reference.png" width="320"/></td>
802+
</tr>
803+
<tr>
804+
<td><b>classic92</b></td>
805+
<td>Horizontal bar chart 🟡 83.1%</td>
806+
</tr>
807+
<tr>
808+
<td><img src="tests/MiniPdf.Benchmark/reports/images/classic92_horizontal_bar_chart_p1_minipdf.png" width="320"/></td>
809+
<td><img src="tests/MiniPdf.Benchmark/reports/images/classic92_horizontal_bar_chart_p1_reference.png" width="320"/></td>
810+
</tr>
811+
<tr>
812+
<td><b>classic93</b></td>
813+
<td>Line chart 🟢 92.9%</td>
814+
</tr>
815+
<tr>
816+
<td><img src="tests/MiniPdf.Benchmark/reports/images/classic93_line_chart_p1_minipdf.png" width="320"/></td>
817+
<td><img src="tests/MiniPdf.Benchmark/reports/images/classic93_line_chart_p1_reference.png" width="320"/></td>
818+
</tr>
819+
<tr>
820+
<td><b>classic94</b></td>
821+
<td>Pie chart 🟡 89.2%</td>
822+
</tr>
823+
<tr>
824+
<td><img src="tests/MiniPdf.Benchmark/reports/images/classic94_pie_chart_p1_minipdf.png" width="320"/></td>
825+
<td><img src="tests/MiniPdf.Benchmark/reports/images/classic94_pie_chart_p1_reference.png" width="320"/></td>
826+
</tr>
827+
<tr>
828+
<td><b>classic95</b></td>
829+
<td>Area chart 🟡 73.3%</td>
830+
</tr>
831+
<tr>
832+
<td><img src="tests/MiniPdf.Benchmark/reports/images/classic95_area_chart_p1_minipdf.png" width="320"/></td>
833+
<td><img src="tests/MiniPdf.Benchmark/reports/images/classic95_area_chart_p1_reference.png" width="320"/></td>
834+
</tr>
835+
<tr>
836+
<td><b>classic96</b></td>
837+
<td>Scatter chart 🟡 87.0%</td>
838+
</tr>
839+
<tr>
840+
<td><img src="tests/MiniPdf.Benchmark/reports/images/classic96_scatter_chart_p1_minipdf.png" width="320"/></td>
841+
<td><img src="tests/MiniPdf.Benchmark/reports/images/classic96_scatter_chart_p1_reference.png" width="320"/></td>
842+
</tr>
843+
<tr>
844+
<td><b>classic97</b></td>
845+
<td>Doughnut chart 🟢 91.3%</td>
846+
</tr>
847+
<tr>
848+
<td><img src="tests/MiniPdf.Benchmark/reports/images/classic97_doughnut_chart_p1_minipdf.png" width="320"/></td>
849+
<td><img src="tests/MiniPdf.Benchmark/reports/images/classic97_doughnut_chart_p1_reference.png" width="320"/></td>
850+
</tr>
851+
<tr>
852+
<td><b>classic98</b></td>
853+
<td>Radar chart 🟡 89.7%</td>
854+
</tr>
855+
<tr>
856+
<td><img src="tests/MiniPdf.Benchmark/reports/images/classic98_radar_chart_p1_minipdf.png" width="320"/></td>
857+
<td><img src="tests/MiniPdf.Benchmark/reports/images/classic98_radar_chart_p1_reference.png" width="320"/></td>
858+
</tr>
859+
<tr>
860+
<td><b>classic99</b></td>
861+
<td>Bubble chart 🟡 83.6%</td>
862+
</tr>
863+
<tr>
864+
<td><img src="tests/MiniPdf.Benchmark/reports/images/classic99_bubble_chart_p1_minipdf.png" width="320"/></td>
865+
<td><img src="tests/MiniPdf.Benchmark/reports/images/classic99_bubble_chart_p1_reference.png" width="320"/></td>
866+
</tr>
867+
<tr>
868+
<td><b>classic100</b></td>
869+
<td>Stacked bar chart 🟢 91.3%</td>
870+
</tr>
871+
<tr>
872+
<td><img src="tests/MiniPdf.Benchmark/reports/images/classic100_stacked_bar_chart_p1_minipdf.png" width="320"/></td>
873+
<td><img src="tests/MiniPdf.Benchmark/reports/images/classic100_stacked_bar_chart_p1_reference.png" width="320"/></td>
874+
</tr>
875+
<tr>
876+
<td><b>classic101</b></td>
877+
<td>Percent stacked bar 🟡 87.1%</td>
878+
</tr>
879+
<tr>
880+
<td><img src="tests/MiniPdf.Benchmark/reports/images/classic101_percent_stacked_bar_p1_minipdf.png" width="320"/></td>
881+
<td><img src="tests/MiniPdf.Benchmark/reports/images/classic101_percent_stacked_bar_p1_reference.png" width="320"/></td>
882+
</tr>
883+
<tr>
884+
<td><b>classic102</b></td>
885+
<td>Line chart with markers 🟢 91.4%</td>
886+
</tr>
887+
<tr>
888+
<td><img src="tests/MiniPdf.Benchmark/reports/images/classic102_line_chart_with_markers_p1_minipdf.png" width="320"/></td>
889+
<td><img src="tests/MiniPdf.Benchmark/reports/images/classic102_line_chart_with_markers_p1_reference.png" width="320"/></td>
890+
</tr>
891+
<tr>
892+
<td><b>classic103</b></td>
893+
<td>Pie chart with labels 🟡 82.3%</td>
894+
</tr>
895+
<tr>
896+
<td><img src="tests/MiniPdf.Benchmark/reports/images/classic103_pie_chart_with_labels_p1_minipdf.png" width="320"/></td>
897+
<td><img src="tests/MiniPdf.Benchmark/reports/images/classic103_pie_chart_with_labels_p1_reference.png" width="320"/></td>
898+
</tr>
899+
<tr>
900+
<td><b>classic104</b></td>
901+
<td>Combo bar line chart 🟡 81.5%</td>
902+
</tr>
903+
<tr>
904+
<td><img src="tests/MiniPdf.Benchmark/reports/images/classic104_combo_bar_line_chart_p1_minipdf.png" width="320"/></td>
905+
<td><img src="tests/MiniPdf.Benchmark/reports/images/classic104_combo_bar_line_chart_p1_reference.png" width="320"/></td>
906+
</tr>
907+
<tr>
908+
<td><b>classic105</b></td>
909+
<td>3d bar chart 🟡 84.2%</td>
910+
</tr>
911+
<tr>
912+
<td><img src="tests/MiniPdf.Benchmark/reports/images/classic105_3d_bar_chart_p1_minipdf.png" width="320"/></td>
913+
<td><img src="tests/MiniPdf.Benchmark/reports/images/classic105_3d_bar_chart_p1_reference.png" width="320"/></td>
914+
</tr>
915+
<tr>
916+
<td><b>classic106</b></td>
917+
<td>3d pie chart 🟢 91.3%</td>
918+
</tr>
919+
<tr>
920+
<td><img src="tests/MiniPdf.Benchmark/reports/images/classic106_3d_pie_chart_p1_minipdf.png" width="320"/></td>
921+
<td><img src="tests/MiniPdf.Benchmark/reports/images/classic106_3d_pie_chart_p1_reference.png" width="320"/></td>
922+
</tr>
923+
<tr>
924+
<td><b>classic107</b></td>
925+
<td>Multi series line 🟡 80.0%</td>
926+
</tr>
927+
<tr>
928+
<td><img src="tests/MiniPdf.Benchmark/reports/images/classic107_multi_series_line_p1_minipdf.png" width="320"/></td>
929+
<td><img src="tests/MiniPdf.Benchmark/reports/images/classic107_multi_series_line_p1_reference.png" width="320"/></td>
930+
</tr>
931+
<tr>
932+
<td><b>classic108</b></td>
933+
<td>Stacked area chart 🟡 89.8%</td>
934+
</tr>
935+
<tr>
936+
<td><img src="tests/MiniPdf.Benchmark/reports/images/classic108_stacked_area_chart_p1_minipdf.png" width="320"/></td>
937+
<td><img src="tests/MiniPdf.Benchmark/reports/images/classic108_stacked_area_chart_p1_reference.png" width="320"/></td>
938+
</tr>
939+
<tr>
940+
<td><b>classic109</b></td>
941+
<td>Scatter with trendline 🟡 82.2%</td>
942+
</tr>
943+
<tr>
944+
<td><img src="tests/MiniPdf.Benchmark/reports/images/classic109_scatter_with_trendline_p1_minipdf.png" width="320"/></td>
945+
<td><img src="tests/MiniPdf.Benchmark/reports/images/classic109_scatter_with_trendline_p1_reference.png" width="320"/></td>
946+
</tr>
947+
<tr>
948+
<td><b>classic110</b></td>
949+
<td>Chart with legend 🟡 82.9%</td>
950+
</tr>
951+
<tr>
952+
<td><img src="tests/MiniPdf.Benchmark/reports/images/classic110_chart_with_legend_p1_minipdf.png" width="320"/></td>
953+
<td><img src="tests/MiniPdf.Benchmark/reports/images/classic110_chart_with_legend_p1_reference.png" width="320"/></td>
954+
</tr>
955+
<tr>
956+
<td><b>classic111</b></td>
957+
<td>Chart with axis labels 🟡 83.2%</td>
958+
</tr>
959+
<tr>
960+
<td><img src="tests/MiniPdf.Benchmark/reports/images/classic111_chart_with_axis_labels_p1_minipdf.png" width="320"/></td>
961+
<td><img src="tests/MiniPdf.Benchmark/reports/images/classic111_chart_with_axis_labels_p1_reference.png" width="320"/></td>
962+
</tr>
963+
<tr>
964+
<td><b>classic112</b></td>
965+
<td>Multiple charts 🟡 84.7%</td>
966+
</tr>
967+
<tr>
968+
<td><img src="tests/MiniPdf.Benchmark/reports/images/classic112_multiple_charts_p1_minipdf.png" width="320"/></td>
969+
<td><img src="tests/MiniPdf.Benchmark/reports/images/classic112_multiple_charts_p1_reference.png" width="320"/></td>
970+
</tr>
971+
<tr>
972+
<td><b>classic113</b></td>
973+
<td>Chart sheet 🟡 81.8%</td>
974+
</tr>
975+
<tr>
976+
<td><img src="tests/MiniPdf.Benchmark/reports/images/classic113_chart_sheet_p1_minipdf.png" width="320"/></td>
977+
<td><img src="tests/MiniPdf.Benchmark/reports/images/classic113_chart_sheet_p1_reference.png" width="320"/></td>
978+
</tr>
979+
<tr>
980+
<td><b>classic114</b></td>
981+
<td>Chart large dataset 🟢 91.0%</td>
982+
</tr>
983+
<tr>
984+
<td><img src="tests/MiniPdf.Benchmark/reports/images/classic114_chart_large_dataset_p1_minipdf.png" width="320"/></td>
985+
<td><img src="tests/MiniPdf.Benchmark/reports/images/classic114_chart_large_dataset_p1_reference.png" width="320"/></td>
986+
</tr>
987+
<tr>
988+
<td><b>classic115</b></td>
989+
<td>Chart negative values 🟢 93.8%</td>
990+
</tr>
991+
<tr>
992+
<td><img src="tests/MiniPdf.Benchmark/reports/images/classic115_chart_negative_values_p1_minipdf.png" width="320"/></td>
993+
<td><img src="tests/MiniPdf.Benchmark/reports/images/classic115_chart_negative_values_p1_reference.png" width="320"/></td>
994+
</tr>
995+
<tr>
996+
<td><b>classic116</b></td>
997+
<td>Percent stacked area 🟡 86.0%</td>
998+
</tr>
999+
<tr>
1000+
<td><img src="tests/MiniPdf.Benchmark/reports/images/classic116_percent_stacked_area_p1_minipdf.png" width="320"/></td>
1001+
<td><img src="tests/MiniPdf.Benchmark/reports/images/classic116_percent_stacked_area_p1_reference.png" width="320"/></td>
1002+
</tr>
1003+
<tr>
1004+
<td><b>classic117</b></td>
1005+
<td>Stock ohlc chart 🟡 80.0%</td>
1006+
</tr>
1007+
<tr>
1008+
<td><img src="tests/MiniPdf.Benchmark/reports/images/classic117_stock_ohlc_chart_p1_minipdf.png" width="320"/></td>
1009+
<td><img src="tests/MiniPdf.Benchmark/reports/images/classic117_stock_ohlc_chart_p1_reference.png" width="320"/></td>
1010+
</tr>
1011+
<tr>
1012+
<td><b>classic118</b></td>
1013+
<td>Bar chart custom colors 🟢 94.6%</td>
1014+
</tr>
1015+
<tr>
1016+
<td><img src="tests/MiniPdf.Benchmark/reports/images/classic118_bar_chart_custom_colors_p1_minipdf.png" width="320"/></td>
1017+
<td><img src="tests/MiniPdf.Benchmark/reports/images/classic118_bar_chart_custom_colors_p1_reference.png" width="320"/></td>
1018+
</tr>
1019+
<tr>
1020+
<td><b>classic119</b></td>
1021+
<td>Dashboard multi charts 🟢 92.2%</td>
1022+
</tr>
1023+
<tr>
1024+
<td><img src="tests/MiniPdf.Benchmark/reports/images/classic119_dashboard_multi_charts_p1_minipdf.png" width="320"/></td>
1025+
<td><img src="tests/MiniPdf.Benchmark/reports/images/classic119_dashboard_multi_charts_p1_reference.png" width="320"/></td>
1026+
</tr>
1027+
<tr>
1028+
<td><b>classic120</b></td>
1029+
<td>Chart with date axis 🔴 64.1%</td>
1030+
</tr>
1031+
<tr>
1032+
<td><img src="tests/MiniPdf.Benchmark/reports/images/classic120_chart_with_date_axis_p1_minipdf.png" width="320"/></td>
1033+
<td><img src="tests/MiniPdf.Benchmark/reports/images/classic120_chart_with_date_axis_p1_reference.png" width="320"/></td>
1034+
</tr>
7951035
</table>
7961036

7971037

7981038

7991039

1040+
1041+
1042+
1043+
8001044
## License
8011045

8021046
This project is licensed under the [Apache License 2.0](LICENSE).

0 commit comments

Comments
 (0)