@@ -20,6 +20,7 @@ A minimal, zero-dependency .NET library for converting Excel (.xlsx) files to PD
2020## Features
2121
2222- ** Excel-to-PDF** — Convert ` .xlsx ` files to paginated PDF with automatic column layout
23+ - ** Embedded images** — JPEG and PNG images embedded in Excel sheets are rendered in the PDF output
2324- ** Zero dependencies** — Uses only built-in .NET APIs (no external packages)
2425- ** Valid PDF 1.4** output
2526- ** Word-to-PDF** — In development
@@ -55,19 +56,19 @@ byte[] pdfBytes = MiniPdf.ConvertToPdf(stream);
5556
5657## Benchmark
5758
58- MiniPdf output is compared against LibreOffice as the reference renderer across ** 60 classic test cases** .
59+ MiniPdf output is compared against LibreOffice as the reference renderer across ** 90 classic test cases** (including 30 image-embedding cases) .
5960
6061| Category | Count | Threshold |
6162| ---| ---| ---|
62- | 🟢 Excellent | 54 | ≥ 90% |
63- | 🟡 Acceptable | 5 | 70% – 90% |
63+ | 🟢 Excellent | 82 | ≥ 90% |
64+ | 🟡 Acceptable | 7 | 70% – 90% |
6465| 🔴 Needs Improvement | 1 | < 70% |
6566
66- ** Average overall score: 96.2 %** (text similarity 40% + visual similarity 40% + page count 20%)
67+ ** Average overall score: 96.4 %** (text similarity 40% + visual similarity 40% + page count 20%)
6768
6869### Visual Comparison
6970
70- All 60 test cases comparing MiniPdf output (left) vs LibreOffice reference (right). Page 1 shown for multi-page results.
71+ All 90 test cases comparing MiniPdf output (left) vs LibreOffice reference (right). Page 1 shown for multi-page results.
7172
7273<table >
7374<tr ><th >Test Case</th ><th >MiniPdf</th ><th >LibreOffice (Reference)</th ><th >Score</th ></tr >
@@ -123,7 +124,7 @@ All 60 test cases comparing MiniPdf output (left) vs LibreOffice reference (righ
123124 <td ><b >classic09</b ><br />Long text<br /><i >MiniPdf: 1 page<br />Reference: 12 pages</i ></td >
124125 <td ><img src =" tests/MiniPdf.Benchmark/reports/images/classic09_long_text_p1_minipdf.png " width =" 320 " /></td >
125126 <td ><img src =" tests/MiniPdf.Benchmark/reports/images/classic09_long_text_p1_reference.png " width =" 320 " /></td >
126- <td >🔴 20.3 %</td >
127+ <td >🔴 21.9 %</td >
127128</tr >
128129<tr >
129130 <td ><b >classic10</b ><br />Special XML characters</td >
@@ -207,7 +208,7 @@ All 60 test cases comparing MiniPdf output (left) vs LibreOffice reference (righ
207208 <td ><b >classic23</b ><br />Unicode text</td >
208209 <td ><img src =" tests/MiniPdf.Benchmark/reports/images/classic23_unicode_text_p1_minipdf.png " width =" 320 " /></td >
209210 <td ><img src =" tests/MiniPdf.Benchmark/reports/images/classic23_unicode_text_p1_reference.png " width =" 320 " /></td >
210- <td >🟡 86 .1%</td >
211+ <td >🟡 87 .1%</td >
211212</tr >
212213<tr >
213214 <td ><b >classic24</b ><br />Red text</td >
@@ -333,7 +334,7 @@ All 60 test cases comparing MiniPdf output (left) vs LibreOffice reference (righ
333334 <td ><b >classic44</b ><br />Employee roster</td >
334335 <td ><img src =" tests/MiniPdf.Benchmark/reports/images/classic44_employee_roster_p1_minipdf.png " width =" 320 " /></td >
335336 <td ><img src =" tests/MiniPdf.Benchmark/reports/images/classic44_employee_roster_p1_reference.png " width =" 320 " /></td >
336- <td >🟡 81.6 %</td >
337+ <td >🟡 87.3 %</td >
337338</tr >
338339<tr >
339340 <td ><b >classic45</b ><br />Sales by region (4 sheets)</td >
@@ -375,7 +376,7 @@ All 60 test cases comparing MiniPdf output (left) vs LibreOffice reference (righ
375376 <td ><b >classic51</b ><br />Product catalog</td >
376377 <td ><img src =" tests/MiniPdf.Benchmark/reports/images/classic51_product_catalog_p1_minipdf.png " width =" 320 " /></td >
377378 <td ><img src =" tests/MiniPdf.Benchmark/reports/images/classic51_product_catalog_p1_reference.png " width =" 320 " /></td >
378- <td >🟡 77.2 %</td >
379+ <td >🟡 81.9 %</td >
379380</tr >
380381<tr >
381382 <td ><b >classic52</b ><br />Pivot summary</td >
@@ -405,13 +406,13 @@ All 60 test cases comparing MiniPdf output (left) vs LibreOffice reference (righ
405406 <td ><b >classic56</b ><br />Alternating row colors</td >
406407 <td ><img src =" tests/MiniPdf.Benchmark/reports/images/classic56_alternating_row_colors_p1_minipdf.png " width =" 320 " /></td >
407408 <td ><img src =" tests/MiniPdf.Benchmark/reports/images/classic56_alternating_row_colors_p1_reference.png " width =" 320 " /></td >
408- <td >🟢 98.9 %</td >
409+ <td >� 75.4 %</td >
409410</tr >
410411<tr >
411412 <td ><b >classic57</b ><br />CJK-only sheet</td >
412413 <td ><img src =" tests/MiniPdf.Benchmark/reports/images/classic57_cjk_only_p1_minipdf.png " width =" 320 " /></td >
413414 <td ><img src =" tests/MiniPdf.Benchmark/reports/images/classic57_cjk_only_p1_reference.png " width =" 320 " /></td >
414- <td >🟡 84.0 %</td >
415+ <td >🟡 85.2 %</td >
415416</tr >
416417<tr >
417418 <td ><b >classic58</b ><br />Mixed numeric formats</td >
@@ -431,6 +432,186 @@ All 60 test cases comparing MiniPdf output (left) vs LibreOffice reference (righ
431432 <td ><img src =" tests/MiniPdf.Benchmark/reports/images/classic60_large_wide_table_p1_reference.png " width =" 320 " /></td >
432433 <td >🟢 94.9%</td >
433434</tr >
435+ <tr >
436+ <td ><b >classic61</b ><br />Product card with image</td >
437+ <td ><img src =" tests/MiniPdf.Benchmark/reports/images/classic61_product_card_with_image_p1_minipdf.png " width =" 320 " /></td >
438+ <td ><img src =" tests/MiniPdf.Benchmark/reports/images/classic61_product_card_with_image_p1_reference.png " width =" 320 " /></td >
439+ <td >🟢 99.3%</td >
440+ </tr >
441+ <tr >
442+ <td ><b >classic62</b ><br />Company logo header</td >
443+ <td ><img src =" tests/MiniPdf.Benchmark/reports/images/classic62_company_logo_header_p1_minipdf.png " width =" 320 " /></td >
444+ <td ><img src =" tests/MiniPdf.Benchmark/reports/images/classic62_company_logo_header_p1_reference.png " width =" 320 " /></td >
445+ <td >🟢 98.8%</td >
446+ </tr >
447+ <tr >
448+ <td ><b >classic63</b ><br />Two products side by side</td >
449+ <td ><img src =" tests/MiniPdf.Benchmark/reports/images/classic63_two_products_side_by_side_p1_minipdf.png " width =" 320 " /></td >
450+ <td ><img src =" tests/MiniPdf.Benchmark/reports/images/classic63_two_products_side_by_side_p1_reference.png " width =" 320 " /></td >
451+ <td >🟢 99.2%</td >
452+ </tr >
453+ <tr >
454+ <td ><b >classic64</b ><br />Employee directory with photo</td >
455+ <td ><img src =" tests/MiniPdf.Benchmark/reports/images/classic64_employee_directory_with_photo_p1_minipdf.png " width =" 320 " /></td >
456+ <td ><img src =" tests/MiniPdf.Benchmark/reports/images/classic64_employee_directory_with_photo_p1_reference.png " width =" 320 " /></td >
457+ <td >🟢 98.1%</td >
458+ </tr >
459+ <tr >
460+ <td ><b >classic65</b ><br />Inventory with product photos</td >
461+ <td ><img src =" tests/MiniPdf.Benchmark/reports/images/classic65_inventory_with_product_photos_p1_minipdf.png " width =" 320 " /></td >
462+ <td ><img src =" tests/MiniPdf.Benchmark/reports/images/classic65_inventory_with_product_photos_p1_reference.png " width =" 320 " /></td >
463+ <td >🟢 98.2%</td >
464+ </tr >
465+ <tr >
466+ <td ><b >classic66</b ><br />Invoice with logo</td >
467+ <td ><img src =" tests/MiniPdf.Benchmark/reports/images/classic66_invoice_with_logo_p1_minipdf.png " width =" 320 " /></td >
468+ <td ><img src =" tests/MiniPdf.Benchmark/reports/images/classic66_invoice_with_logo_p1_reference.png " width =" 320 " /></td >
469+ <td >🟢 96.2%</td >
470+ </tr >
471+ <tr >
472+ <td ><b >classic67</b ><br />Real estate listing</td >
473+ <td ><img src =" tests/MiniPdf.Benchmark/reports/images/classic67_real_estate_listing_p1_minipdf.png " width =" 320 " /></td >
474+ <td ><img src =" tests/MiniPdf.Benchmark/reports/images/classic67_real_estate_listing_p1_reference.png " width =" 320 " /></td >
475+ <td >🟢 98.5%</td >
476+ </tr >
477+ <tr >
478+ <td ><b >classic68</b ><br />Restaurant menu with photos</td >
479+ <td ><img src =" tests/MiniPdf.Benchmark/reports/images/classic68_restaurant_menu_p1_minipdf.png " width =" 320 " /></td >
480+ <td ><img src =" tests/MiniPdf.Benchmark/reports/images/classic68_restaurant_menu_p1_reference.png " width =" 320 " /></td >
481+ <td >🟢 92.3%</td >
482+ </tr >
483+ <tr >
484+ <td ><b >classic69</b ><br />Image-only sheet</td >
485+ <td ><img src =" tests/MiniPdf.Benchmark/reports/images/classic69_image_only_sheet_p1_minipdf.png " width =" 320 " /></td >
486+ <td ><img src =" tests/MiniPdf.Benchmark/reports/images/classic69_image_only_sheet_p1_reference.png " width =" 320 " /></td >
487+ <td >🟢 99.1%</td >
488+ </tr >
489+ <tr >
490+ <td ><b >classic70</b ><br />Product catalog with images</td >
491+ <td ><img src =" tests/MiniPdf.Benchmark/reports/images/classic70_product_catalog_with_images_p1_minipdf.png " width =" 320 " /></td >
492+ <td ><img src =" tests/MiniPdf.Benchmark/reports/images/classic70_product_catalog_with_images_p1_reference.png " width =" 320 " /></td >
493+ <td >🟢 96.3%</td >
494+ </tr >
495+ <tr >
496+ <td ><b >classic71</b ><br />Multi-sheet with images (3 sheets)</td >
497+ <td ><img src =" tests/MiniPdf.Benchmark/reports/images/classic71_multi_sheet_with_images_p1_minipdf.png " width =" 320 " /></td >
498+ <td ><img src =" tests/MiniPdf.Benchmark/reports/images/classic71_multi_sheet_with_images_p1_reference.png " width =" 320 " /></td >
499+ <td >🟢 99.2%</td >
500+ </tr >
501+ <tr >
502+ <td ><b >classic72</b ><br />Bar chart image with data</td >
503+ <td ><img src =" tests/MiniPdf.Benchmark/reports/images/classic72_bar_chart_image_with_data_p1_minipdf.png " width =" 320 " /></td >
504+ <td ><img src =" tests/MiniPdf.Benchmark/reports/images/classic72_bar_chart_image_with_data_p1_reference.png " width =" 320 " /></td >
505+ <td >🟢 97.7%</td >
506+ </tr >
507+ <tr >
508+ <td ><b >classic73</b ><br />Event flyer with banner</td >
509+ <td ><img src =" tests/MiniPdf.Benchmark/reports/images/classic73_event_flyer_with_banner_p1_minipdf.png " width =" 320 " /></td >
510+ <td ><img src =" tests/MiniPdf.Benchmark/reports/images/classic73_event_flyer_with_banner_p1_reference.png " width =" 320 " /></td >
511+ <td >🟢 93.9%</td >
512+ </tr >
513+ <tr >
514+ <td ><b >classic74</b ><br />Dashboard with KPI image</td >
515+ <td ><img src =" tests/MiniPdf.Benchmark/reports/images/classic74_dashboard_with_kpi_image_p1_minipdf.png " width =" 320 " /></td >
516+ <td ><img src =" tests/MiniPdf.Benchmark/reports/images/classic74_dashboard_with_kpi_image_p1_reference.png " width =" 320 " /></td >
517+ <td >🟢 97.2%</td >
518+ </tr >
519+ <tr >
520+ <td ><b >classic75</b ><br />Certificate with seal</td >
521+ <td ><img src =" tests/MiniPdf.Benchmark/reports/images/classic75_certificate_with_seal_p1_minipdf.png " width =" 320 " /></td >
522+ <td ><img src =" tests/MiniPdf.Benchmark/reports/images/classic75_certificate_with_seal_p1_reference.png " width =" 320 " /></td >
523+ <td >🟢 99.2%</td >
524+ </tr >
525+ <tr >
526+ <td ><b >classic76</b ><br />Product image grid (2×2)</td >
527+ <td ><img src =" tests/MiniPdf.Benchmark/reports/images/classic76_product_image_grid_p1_minipdf.png " width =" 320 " /></td >
528+ <td ><img src =" tests/MiniPdf.Benchmark/reports/images/classic76_product_image_grid_p1_reference.png " width =" 320 " /></td >
529+ <td >🟢 98.5%</td >
530+ </tr >
531+ <tr >
532+ <td ><b >classic77</b ><br />News article with hero image</td >
533+ <td ><img src =" tests/MiniPdf.Benchmark/reports/images/classic77_news_article_with_hero_image_p1_minipdf.png " width =" 320 " /></td >
534+ <td ><img src =" tests/MiniPdf.Benchmark/reports/images/classic77_news_article_with_hero_image_p1_reference.png " width =" 320 " /></td >
535+ <td >🟢 97.3%</td >
536+ </tr >
537+ <tr >
538+ <td ><b >classic78</b ><br />Small icon per row</td >
539+ <td ><img src =" tests/MiniPdf.Benchmark/reports/images/classic78_small_icon_per_row_p1_minipdf.png " width =" 320 " /></td >
540+ <td ><img src =" tests/MiniPdf.Benchmark/reports/images/classic78_small_icon_per_row_p1_reference.png " width =" 320 " /></td >
541+ <td >🟢 95.9%</td >
542+ </tr >
543+ <tr >
544+ <td ><b >classic79</b ><br />Wide panoramic banner</td >
545+ <td ><img src =" tests/MiniPdf.Benchmark/reports/images/classic79_wide_panoramic_banner_p1_minipdf.png " width =" 320 " /></td >
546+ <td ><img src =" tests/MiniPdf.Benchmark/reports/images/classic79_wide_panoramic_banner_p1_reference.png " width =" 320 " /></td >
547+ <td >🟢 97.7%</td >
548+ </tr >
549+ <tr >
550+ <td ><b >classic80</b ><br />Portrait tall image</td >
551+ <td ><img src =" tests/MiniPdf.Benchmark/reports/images/classic80_portrait_tall_image_p1_minipdf.png " width =" 320 " /></td >
552+ <td ><img src =" tests/MiniPdf.Benchmark/reports/images/classic80_portrait_tall_image_p1_reference.png " width =" 320 " /></td >
553+ <td >🟢 98.9%</td >
554+ </tr >
555+ <tr >
556+ <td ><b >classic81</b ><br />Step-by-step with images</td >
557+ <td ><img src =" tests/MiniPdf.Benchmark/reports/images/classic81_step_by_step_with_images_p1_minipdf.png " width =" 320 " /></td >
558+ <td ><img src =" tests/MiniPdf.Benchmark/reports/images/classic81_step_by_step_with_images_p1_reference.png " width =" 320 " /></td >
559+ <td >🟢 98.7%</td >
560+ </tr >
561+ <tr >
562+ <td ><b >classic82</b ><br />Before/after images</td >
563+ <td ><img src =" tests/MiniPdf.Benchmark/reports/images/classic82_before_after_images_p1_minipdf.png " width =" 320 " /></td >
564+ <td ><img src =" tests/MiniPdf.Benchmark/reports/images/classic82_before_after_images_p1_reference.png " width =" 320 " /></td >
565+ <td >🟢 97.4%</td >
566+ </tr >
567+ <tr >
568+ <td ><b >classic83</b ><br />Color swatch palette</td >
569+ <td ><img src =" tests/MiniPdf.Benchmark/reports/images/classic83_color_swatch_palette_p1_minipdf.png " width =" 320 " /></td >
570+ <td ><img src =" tests/MiniPdf.Benchmark/reports/images/classic83_color_swatch_palette_p1_reference.png " width =" 320 " /></td >
571+ <td >🟢 97.4%</td >
572+ </tr >
573+ <tr >
574+ <td ><b >classic84</b ><br />Travel destination cards</td >
575+ <td ><img src =" tests/MiniPdf.Benchmark/reports/images/classic84_travel_destination_cards_p1_minipdf.png " width =" 320 " /></td >
576+ <td ><img src =" tests/MiniPdf.Benchmark/reports/images/classic84_travel_destination_cards_p1_reference.png " width =" 320 " /></td >
577+ <td >🟢 97.8%</td >
578+ </tr >
579+ <tr >
580+ <td ><b >classic85</b ><br />Lab results with image</td >
581+ <td ><img src =" tests/MiniPdf.Benchmark/reports/images/classic85_lab_results_with_image_p1_minipdf.png " width =" 320 " /></td >
582+ <td ><img src =" tests/MiniPdf.Benchmark/reports/images/classic85_lab_results_with_image_p1_reference.png " width =" 320 " /></td >
583+ <td >🟢 97.2%</td >
584+ </tr >
585+ <tr >
586+ <td ><b >classic86</b ><br />Software screenshot features</td >
587+ <td ><img src =" tests/MiniPdf.Benchmark/reports/images/classic86_software_screenshot_features_p1_minipdf.png " width =" 320 " /></td >
588+ <td ><img src =" tests/MiniPdf.Benchmark/reports/images/classic86_software_screenshot_features_p1_reference.png " width =" 320 " /></td >
589+ <td >🟢 97.1%</td >
590+ </tr >
591+ <tr >
592+ <td ><b >classic87</b ><br />Sports results with logos</td >
593+ <td ><img src =" tests/MiniPdf.Benchmark/reports/images/classic87_sports_results_with_logos_p1_minipdf.png " width =" 320 " /></td >
594+ <td ><img src =" tests/MiniPdf.Benchmark/reports/images/classic87_sports_results_with_logos_p1_reference.png " width =" 320 " /></td >
595+ <td >🟢 99.5%</td >
596+ </tr >
597+ <tr >
598+ <td ><b >classic88</b ><br />Image after data</td >
599+ <td ><img src =" tests/MiniPdf.Benchmark/reports/images/classic88_image_after_data_p1_minipdf.png " width =" 320 " /></td >
600+ <td ><img src =" tests/MiniPdf.Benchmark/reports/images/classic88_image_after_data_p1_reference.png " width =" 320 " /></td >
601+ <td >🟢 98.9%</td >
602+ </tr >
603+ <tr >
604+ <td ><b >classic89</b ><br />Nutrition label with image</td >
605+ <td ><img src =" tests/MiniPdf.Benchmark/reports/images/classic89_nutrition_label_with_image_p1_minipdf.png " width =" 320 " /></td >
606+ <td ><img src =" tests/MiniPdf.Benchmark/reports/images/classic89_nutrition_label_with_image_p1_reference.png " width =" 320 " /></td >
607+ <td >🟢 96.5%</td >
608+ </tr >
609+ <tr >
610+ <td ><b >classic90</b ><br />Project status with milestones</td >
611+ <td ><img src =" tests/MiniPdf.Benchmark/reports/images/classic90_project_status_with_milestones_p1_minipdf.png " width =" 320 " /></td >
612+ <td ><img src =" tests/MiniPdf.Benchmark/reports/images/classic90_project_status_with_milestones_p1_reference.png " width =" 320 " /></td >
613+ <td >🟡 87.2%</td >
614+ </tr >
434615</table >
435616
436617## License
0 commit comments