diff --git a/app/components/people/PeopleView.vue b/app/components/people/PeopleView.vue
index e579dd7..28722da 100644
--- a/app/components/people/PeopleView.vue
+++ b/app/components/people/PeopleView.vue
@@ -164,7 +164,7 @@
diff --git a/app/plugins/01-common.js b/app/plugins/01-common.js
index c641566..0bdf78e 100644
--- a/app/plugins/01-common.js
+++ b/app/plugins/01-common.js
@@ -232,61 +232,6 @@ export default defineNuxtPlugin((nuxtApp) => {
return id;
};
- const exportpdf = function (docid, name, size, orientation = "portrait") {
- var element = document.getElementById(docid);
- let elms = element.querySelectorAll("[id='ignore']");
- for (var i = 0; i < elms.length; i++) {
- elms[i].style.setProperty("display", "none", "important");
- }
- // Xóa cache ảnh để lần export sau không bị lỗi
- element.querySelectorAll("img").forEach((img) => {
- img.src = `${img.src}`;
- });
- var opt = {
- margin: 0.4,
- filename: `${name || "file"}-${dayjs().format("YYYYMMDDHHmmss")}.pdf`,
- image: { type: "jpeg", quality: 1 },
- html2canvas: { scale: 3, useCORS: true },
- jsPDF: { unit: "in", format: size || "a4", orientation },
-
- pagebreak: {
- mode: ["avoid-all", "css", "legacy"],
- before: ".page-break-before",
- after: ".page-break-after",
- avoid: ".avoid-page-break",
- },
- };
- setTimeout(() => html2pdf().set(opt).from(element).save(), 300);
- setTimeout(() => {
- for (var i = 0; i < elms.length; i++) {
- elms[i].style.removeProperty("display");
- }
- }, 1000);
- return opt.filename;
- };
-
- const exportImage = function (docid, name) {
- var element = document.getElementById(docid);
- let elms = element.querySelectorAll("[id='ignore']");
- for (var i = 0; i < elms.length; i++) {
- elms[i].style.display = "none";
- }
- let filename = `${name}-${dayjs().format("YYYYMMDDHHmmss")}.png`;
- html2canvas(element).then((canvas) => {
- const link = document.createElement("a");
- link.href = canvas.toDataURL("image/png");
- link.download = filename;
- link.click();
- link.remove();
- });
- setTimeout(() => {
- for (var i = 0; i < elms.length; i++) {
- elms[i].style.display = "block";
- }
- }, 1000);
- return filename;
- };
-
const download = async function (url, fileName) {
const name = dayjs(new Date()).format("YYYYMMDDhhmmss") + "-" + fileName;
const response = await fetch(url);
@@ -549,8 +494,6 @@ export default defineNuxtPlugin((nuxtApp) => {
copyToClipboard,
nonAccent,
linkID,
- exportpdf,
- exportImage,
vnmoney,
createMeta,
dayjs,
diff --git a/app/utils/exportImage.js b/app/utils/exportImage.js
new file mode 100644
index 0000000..a8d0c13
--- /dev/null
+++ b/app/utils/exportImage.js
@@ -0,0 +1,28 @@
+import dayjs from "dayjs";
+import html2canvas from "html2canvas-pro";
+
+export default async function exportImage(docid, filename = "file") {
+ const target = document.getElementById(docid);
+
+ const ignored = target.querySelectorAll(".ignore");
+ ignored.forEach((el) => el.style.setProperty("display", "none", "important"));
+ // Xóa cache ảnh để lần export sau không bị lỗi
+ target.querySelectorAll("img").forEach((img) => (img.src = `${img.src}`));
+ const restoreIcons = swapIconsForExport(target);
+
+ try {
+ await new Promise((r) => requestAnimationFrame(r));
+
+ const canvas = await html2canvas(target);
+ const link = document.createElement("a");
+ link.href = canvas.toDataURL("image/png");
+ link.download = `${filename}-${dayjs().format("YYYYMMDDHHmmss")}.png`;
+ link.click();
+ link.remove();
+ } finally {
+ restoreIcons();
+ ignored.forEach((el) => el.style.removeProperty("display"));
+ }
+
+ return filename;
+}
diff --git a/app/utils/exportPdf.js b/app/utils/exportPdf.js
new file mode 100644
index 0000000..f6901f7
--- /dev/null
+++ b/app/utils/exportPdf.js
@@ -0,0 +1,35 @@
+import dayjs from "dayjs";
+import html2pdf from "html2pdf.js";
+
+export default async function exportPdf(docid, { filename = "file", format = "a4", orientation = "portrait" } = {}) {
+ const target = document.getElementById(docid);
+
+ const ignored = target.querySelectorAll(".ignore");
+ ignored.forEach((el) => el.style.setProperty("display", "none", "important"));
+ // Xóa cache ảnh để lần export sau không bị lỗi
+ target.querySelectorAll("img").forEach((img) => (img.src = `${img.src}`));
+ const restoreIcons = swapIconsForExport(target);
+
+ const opt = {
+ margin: 3,
+ filename: `${filename}-${dayjs().format("YYYYMMDDHHmmss")}.pdf`,
+ jsPDF: { format, orientation, unit: "mm" },
+ html2canvas: { scale: 3, useCORS: true },
+ image: { type: "jpeg", quality: 1 },
+ pagebreak: {
+ mode: ["avoid-all", "css", "legacy"],
+ before: ".page-break-before",
+ after: ".page-break-after",
+ avoid: ".avoid-page-break",
+ },
+ };
+
+ try {
+ await new Promise((r) => requestAnimationFrame(r));
+ await html2pdf().set(opt).from(target).save();
+ } finally {
+ restoreIcons();
+ ignored.forEach((el) => el.style.removeProperty("display"));
+ }
+ return opt.filename;
+}
diff --git a/app/utils/iconSwap.js b/app/utils/iconSwap.js
new file mode 100644
index 0000000..86feaa8
--- /dev/null
+++ b/app/utils/iconSwap.js
@@ -0,0 +1,52 @@
+const ICONIFY_SELECTOR = '[class*="iconify"]';
+
+/**
+ * Replaces iconify CSS-mask spans with real