diff --git a/client/package-lock.json b/client/package-lock.json index 9c48299..432e6fb 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -24,6 +24,7 @@ "antd": "^5.20.0", "axios": "^1.7.3", "flag-icons": "^7.2.3", + "html-to-image": "^1.11.11", "i18next": "^23.12.2", "i18next-browser-languagedetector": "^8.0.0", "i18next-http-backend": "^2.5.2", @@ -5497,6 +5498,11 @@ "void-elements": "3.1.0" } }, + "node_modules/html-to-image": { + "version": "1.11.11", + "resolved": "https://registry.npmjs.org/html-to-image/-/html-to-image-1.11.11.tgz", + "integrity": "sha512-9gux8QhvjRO/erSnDPv28noDZcPZmYE7e1vFsBLKLlRlKDSqNJYebj6Qz1TGd5lsRV+X+xYyjCKjuZdABinWjA==" + }, "node_modules/htmlparser2": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz", diff --git a/client/package.json b/client/package.json index 9256db1..52fdb71 100644 --- a/client/package.json +++ b/client/package.json @@ -23,6 +23,7 @@ "antd": "^5.20.0", "axios": "^1.7.3", "flag-icons": "^7.2.3", + "html-to-image": "^1.11.11", "i18next": "^23.12.2", "i18next-browser-languagedetector": "^8.0.0", "i18next-http-backend": "^2.5.2", diff --git a/client/public/locales/en/common.json b/client/public/locales/en/common.json index be4c583..f587379 100644 --- a/client/public/locales/en/common.json +++ b/client/public/locales/en/common.json @@ -99,7 +99,8 @@ "deleteSettings": "Delete Current Preset", "deleteSettingsConfirm": "Are you sure you want to delete this preset?", "settingsName": "Preset Name", - "saveSetting": "Save Presets" + "saveSetting": "Save Presets", + "saveAsImage": "Save as Image" }, "qrcode": { "button": "Print Labels", diff --git a/client/src/pages/printing/printingDialog.tsx b/client/src/pages/printing/printingDialog.tsx index 88fd699..50c5482 100644 --- a/client/src/pages/printing/printingDialog.tsx +++ b/client/src/pages/printing/printingDialog.tsx @@ -1,4 +1,4 @@ -import { PrinterOutlined } from "@ant-design/icons"; +import { FileImageOutlined, PrinterOutlined } from "@ant-design/icons"; import { useTranslate } from "@refinedev/core"; import { Button, @@ -14,6 +14,7 @@ import { Slider, Space, } from "antd"; +import * as htmlToImage from "html-to-image"; import React, { useRef } from "react"; import ReactToPrint from "react-to-print"; import { useSavedState } from "../../utils/saveload"; @@ -119,6 +120,7 @@ const PrintingDialog: React.FC = ({ return (
= ({ ); }); + const saveAsImage = () => { + const hasPrinted: Element[] = []; + + Array.from(document.getElementsByClassName("print-qrcode-item")).forEach(async (item) => { + // Prevent printing copies + for (let i = 0; i < hasPrinted.length; i += 1) { + if (item.isEqualNode(hasPrinted[i])) return; + } + hasPrinted.push(item); + + // Generate png image + const url = await htmlToImage.toPng(item as HTMLElement, { + backgroundColor: "#FFF", + cacheBust: true, + }); + + // Download image + const link = document.createElement("a"); + link.href = url; + link.download = "spoolmanlabel.png"; + link.click(); + }); + }; + return ( <> @@ -788,6 +814,9 @@ const PrintingDialog: React.FC = ({ {extraButtons} + (