{"id":32136750,"url":"https://github.com/plutoprint/plutoprint","last_synced_at":"2026-01-09T22:51:57.738Z","repository":{"id":238173630,"uuid":"796010781","full_name":"plutoprint/plutoprint","owner":"plutoprint","description":"A Python Library for Generating PDFs and Images from HTML, powered by PlutoBook","archived":false,"fork":false,"pushed_at":"2025-09-23T20:49:14.000Z","size":638,"stargazers_count":970,"open_issues_count":2,"forks_count":31,"subscribers_count":9,"default_branch":"main","last_synced_at":"2025-10-02T02:52:01.231Z","etag":null,"topics":["css","html","html-to-image","html-to-pdf","image-generator","pdf","pdf-generator","plutobook","python","svg"],"latest_commit_sha":null,"homepage":"https://plutoprint.readthedocs.io","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/plutoprint.png","metadata":{"files":{"readme":"README.rst","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2024-05-04T17:00:47.000Z","updated_at":"2025-10-01T16:46:20.000Z","dependencies_parsed_at":"2024-05-04T19:22:24.221Z","dependency_job_id":"1af0a632-c365-4560-b83a-00587a2c22c5","html_url":"https://github.com/plutoprint/plutoprint","commit_stats":null,"previous_names":["plutoprint/plutoprint"],"tags_count":13,"template":false,"template_full_name":null,"purl":"pkg:github/plutoprint/plutoprint","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/plutoprint%2Fplutoprint","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/plutoprint%2Fplutoprint/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/plutoprint%2Fplutoprint/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/plutoprint%2Fplutoprint/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/plutoprint","download_url":"https://codeload.github.com/plutoprint/plutoprint/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/plutoprint%2Fplutoprint/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":280200872,"owners_count":26289477,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-21T02:00:06.614Z","response_time":58,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["css","html","html-to-image","html-to-pdf","image-generator","pdf","pdf-generator","plutobook","python","svg"],"created_at":"2025-10-21T04:04:38.021Z","updated_at":"2026-01-09T22:51:57.725Z","avatar_url":"https://github.com/plutoprint.png","language":"Python","funding_links":["https://github.com/sponsors/plutoprint"],"categories":[],"sub_categories":[],"readme":"|build| |docs| |license| |downloads| |pypi| |pyver|\n\nPlutoPrint\n==========\n\nPlutoPrint is a lightweight and easy-to-use Python library for generating high-quality PDFs and images directly from HTML or XML content. It is based on `PlutoBook’s \u003chttps://github.com/plutoprint/plutobook\u003e`_ robust rendering engine and provides a simple API to convert your HTML into crisp PDF documents or vibrant image files. This makes it ideal for reports, invoices, or visual snapshots.\n\n.. list-table::\n   :header-rows: 1\n\n   * - Invoices\n     - Tickets\n   * - |invoices|\n     - |tickets|\n\nInstallation\n------------\n\n.. code-block:: bash\n\n   pip install plutoprint\n\nPlutoPrint requires `PlutoBook \u003chttps://github.com/plutoprint/plutobook\u003e`_. On Windows (``win_amd64``), Linux (``manylinux_2_28_x86_64``) and macOS (``macosx_14_0_arm64``), prebuilt binaries are bundled with the package and no further steps are necessary. On other architectures or when building from source, see the `Getting Started guide \u003chttps://plutoprint.readthedocs.io/en/latest/getting_started.html\u003e`_ for dependency setup and build instructions.\n\nOn **macOS** and **Linux**, you can also install PlutoPrint using `Homebrew \u003chttps://formulae.brew.sh/formula/plutoprint\u003e`_:\n\n.. code-block:: bash\n\n   brew update\n   brew install plutoprint\n\nQuick Usage\n-----------\n\nGenerate a PDF from the command line with the installed ``plutoprint`` script:\n\n.. code-block:: bash\n\n   plutoprint input.html output.pdf --size=A4\n\nGenerate PDF with Python\n^^^^^^^^^^^^^^^^^^^^^^^^\n\n.. code-block:: python\n\n   import plutoprint\n\n   book = plutoprint.Book(plutoprint.PAGE_SIZE_A4)\n   book.load_url(\"hello.html\")\n\n   # Export the entire document to PDF\n   book.write_to_pdf(\"hello.pdf\")\n\n   # Export pages 2 to 15 (inclusive) in order\n   book.write_to_pdf(\"hello-range.pdf\", 2, 15, 1)\n\n   # Export pages 15 to 2 (inclusive) in reverse order\n   book.write_to_pdf(\"hello-reverse.pdf\", 15, 2, -1)\n\n   # Render pages manually with PDFCanvas (in reverse order)\n   with plutoprint.PDFCanvas(\"hello-canvas.pdf\", book.get_page_size()) as canvas:\n      canvas.scale(plutoprint.UNITS_PX, plutoprint.UNITS_PX)\n      for page_index in range(book.get_page_count() - 1, -1, -1):\n         canvas.set_size(book.get_page_size_at(page_index))\n         book.render_page(canvas, page_index)\n         canvas.show_page()\n\nGenerate PNG with Python\n^^^^^^^^^^^^^^^^^^^^^^^^\n\n.. code-block:: python\n\n   import plutoprint\n   import math\n\n   book = plutoprint.Book(media=plutoprint.MEDIA_TYPE_SCREEN)\n   book.load_html(\"\u003cb\u003eHello World\u003c/b\u003e\", user_style=\"body { text-align: center }\")\n\n   # Outputs an image at the document’s natural size\n   book.write_to_png(\"hello.png\")\n\n   # Outputs a 320px wide image with auto-scaled height\n   book.write_to_png(\"hello-width.png\", width=320)\n\n   # Outputs a 240px tall image with auto-scaled width\n   book.write_to_png(\"hello-height.png\", height=240)\n\n   # Outputs an 800×200 pixels image (may stretch/squish content)\n   book.write_to_png(\"hello-fixed.png\", 800, 200)\n\n   # Get the natural document size\n   width = math.ceil(book.get_document_width())\n   height = math.ceil(book.get_document_height())\n\n   # Outputs a high-resolution 5x scaled image\n   book.write_to_png(\"hello-scaled.png\", width * 5, height * 5)\n\n   # Render manually on a canvas with white background\n   with plutoprint.ImageCanvas(width, height) as canvas:\n      canvas.clear_surface(1, 1, 1)\n      book.render_document(canvas)\n      canvas.write_to_png(\"hello-canvas.png\")\n\nGenerate QR Codes\n^^^^^^^^^^^^^^^^^\n\nQuick example of using ``-pluto-qrcode(\u003cstring\u003e[, \u003ccolor\u003e])`` to create QR codes with optional colors.\n\n.. code-block:: python\n\n   import plutoprint\n\n   HTML_CONTENT = \"\"\"\n   \u003ctable\u003e\n     \u003ctr\u003e\n       \u003cth class=\"email\"\u003eEmail\u003c/th\u003e\n       \u003cth class=\"tel\"\u003eTel\u003c/th\u003e\n     \u003c/tr\u003e\n     \u003ctr\u003e\n       \u003cth class=\"website\"\u003eWebsite\u003c/th\u003e\n       \u003cth class=\"github\"\u003eGitHub\u003c/th\u003e\n     \u003c/tr\u003e\n   \u003c/table\u003e\n   \"\"\"\n\n   USER_STYLE = \"\"\"\n   body {\n     margin: 0;\n     height: 100vh;\n     display: flex;\n     justify-content: center;\n     align-items: center;\n     background: #f7f7f7;\n     font: 16px Arial;\n   }\n\n   table {\n     border-spacing: 2rem;\n     background: #fff;\n     padding: 2rem;\n     border: 1px solid #ccc;\n     border-radius: 16px;\n   }\n\n   th::before {\n     display: block;\n     width: 130px;\n     height: 130px;\n     margin: 0 auto 0.8rem;\n   }\n\n   .email::before   { content: -pluto-qrcode('mailto:contact@example.com', #16a34a); }\n   .tel::before     { content: -pluto-qrcode('tel:+1234567890', #2563eb); }\n   .website::before { content: -pluto-qrcode('https://example.com', #ef4444); }\n   .github::before  { content: -pluto-qrcode('https://github.com/plutoprint', #f59e0b); }\n   \"\"\"\n\n   book = plutoprint.Book(plutoprint.PAGE_SIZE_LETTER.landscape())\n   book.load_html(HTML_CONTENT, USER_STYLE)\n   book.write_to_png(\"qrcard.png\")\n   book.write_to_pdf(\"qrcard.pdf\")\n\nExpected output:\n\n.. image:: https://raw.githubusercontent.com/plutoprint/plutoprint-samples/main/qrcard.png\n   :alt: QR card\n\nGenerate Charts with Matplotlib\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\n.. code-block:: python\n\n   import plutoprint\n\n   import matplotlib.pyplot as plt\n   import urllib.parse\n   import io\n\n   class CustomResourceFetcher(plutoprint.ResourceFetcher):\n      def fetch_url(self, url):\n         if not url.startswith('chart:'):\n            return super().fetch_url(url)\n         values = [float(v) for v in urllib.parse.unquote(url[6:]).split(',')]\n         labels = [chr(65 + i) for i in range(len(values))]\n\n         plt.bar(labels, values)\n         plt.title('Bar Chart')\n         plt.xlabel('Labels')\n         plt.ylabel('Values')\n\n         buffer = io.BytesIO()\n         plt.savefig(buffer, format='svg', transparent=True)\n\n         return plutoprint.ResourceData(buffer.getvalue(), \"image/svg+xml\", \"utf-8\")\n\n   book = plutoprint.Book(plutoprint.PAGE_SIZE_A4.landscape(), plutoprint.PAGE_MARGINS_NONE)\n\n   book.custom_resource_fetcher = CustomResourceFetcher()\n\n   HTML_CONTENT = \"\"\"\n   \u003cbody\u003e\n     \u003cimg src='chart:23,45,12,36,28,50'\u003e\n     \u003cimg src='chart:5,15,25,35,45'\u003e\n     \u003cimg src='chart:50,40,30,20,10'\u003e\n     \u003cimg src='chart:10,20,30,40,50,60,70'\u003e\n   \u003c/body\u003e\n   \"\"\"\n\n   USER_STYLE = \"\"\"\n   body {\n     display: flex;\n     flex-wrap: wrap;\n     justify-content: center;\n     align-items: center;\n     background: #f7f7f7;\n     height: 100vh;\n     margin: 0;\n   }\n\n   img {\n     background: #fff;\n     border: 1px solid #ccc;\n     margin: auto;\n     max-height: 45vh;\n   }\n   \"\"\"\n\n   book.load_html(HTML_CONTENT, USER_STYLE)\n   book.write_to_png(\"charts.png\")\n   book.write_to_pdf(\"charts.pdf\")\n\nExpected output:\n\n.. image:: https://raw.githubusercontent.com/plutoprint/plutoprint-samples/main/charts.png\n   :alt: Charts\n\nSamples\n=======\n\n.. list-table:: Invoices\n\n   * - .. image:: https://raw.githubusercontent.com/plutoprint/plutoprint-samples/main/images/invoice-1.png\n          :alt: Invoice 1\n     - .. image:: https://raw.githubusercontent.com/plutoprint/plutoprint-samples/main/images/invoice-2.png\n          :alt: Invoice 2\n     - .. image:: https://raw.githubusercontent.com/plutoprint/plutoprint-samples/main/images/invoice-3.png\n          :alt: Invoice 3\n\n.. list-table:: Tickets\n\n   * - .. image:: https://raw.githubusercontent.com/plutoprint/plutoprint-samples/main/images/ticket-1.png\n          :alt: Ticket 1\n     - .. image:: https://raw.githubusercontent.com/plutoprint/plutoprint-samples/main/images/ticket-2.png\n          :alt: Ticket 2\n   * - .. image:: https://raw.githubusercontent.com/plutoprint/plutoprint-samples/main/images/ticket-3.png\n          :alt: Ticket 3\n     - .. image:: https://raw.githubusercontent.com/plutoprint/plutoprint-samples/main/images/ticket-4.png\n          :alt: Ticket 4\n\nLinks \u0026 Resources\n=================\n\n- Documentation: https://plutoprint.readthedocs.io\n- Samples: https://github.com/plutoprint/plutoprint-samples\n- Code: https://github.com/plutoprint/plutoprint\n- Issues: https://github.com/plutoprint/plutoprint/issues\n- Donation: https://github.com/sponsors/plutoprint\n\nSupport and Contribution\n========================\n\nThis project continues to grow through the encouragement and involvement of its users. If it has been helpful to you or your team, here are a few meaningful ways you can support its future:\n\n- **Give it a Star on GitHub.** Starring the project helps others discover it and shows your appreciation for the work behind it.\n- **Sponsor the project** to help drive new features, improve stability, and ensure the project continues to evolve for everyone who relies on it.\n- **Share your feedback.** If you have suggestions, feature requests, or notice an issue, please open a GitHub issue. Your voice and experience help guide the project’s direction.\n\n.. image:: https://api.star-history.com/svg?repos=plutoprint/plutoprint\u0026type=date\u0026logscale\u0026legend=top-left\n   :alt: Star History Chart\n\nLicense\n=======\n\nPlutoPrint is licensed under the `MIT License \u003chttps://github.com/plutoprint/plutoprint/blob/main/LICENSE\u003e`_, allowing for both personal and commercial use.\n\n.. |build| image:: https://img.shields.io/github/actions/workflow/status/plutoprint/plutoprint/main.yml\n   :target: https://github.com/plutoprint/plutoprint/actions\n.. |docs| image:: https://img.shields.io/readthedocs/plutoprint\n   :target: https://plutoprint.readthedocs.io\n.. |license| image:: https://img.shields.io/pypi/l/plutoprint\n   :target: https://github.com/plutoprint/plutoprint/blob/main/LICENSE\n.. |downloads| image:: https://img.shields.io/pypi/dm/plutoprint\n.. |pypi| image:: https://img.shields.io/pypi/v/plutoprint\n   :target: https://pypi.org/project/plutoprint\n.. |pyver| image:: https://img.shields.io/pypi/pyversions/plutoprint\n.. |invoices| image:: https://raw.githubusercontent.com/plutoprint/plutoprint-samples/main/images/invoices.png\n   :alt: Invoices\n.. |tickets| image:: https://raw.githubusercontent.com/plutoprint/plutoprint-samples/main/images/tickets.jpg\n   :alt: Tickets\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fplutoprint%2Fplutoprint","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fplutoprint%2Fplutoprint","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fplutoprint%2Fplutoprint/lists"}