|
@@ -1,11 +1,11 @@
|
|
|
// 下载文件
|
|
|
import axios from "axios";
|
|
|
import { showToast } from "vant";
|
|
|
-import {ref} from 'vue'
|
|
|
-
|
|
|
+import { ref } from "vue";
|
|
|
+import { PDFDocument } from "pdf-lib";
|
|
|
|
|
|
/**
|
|
|
- *
|
|
|
+ * 下载文件
|
|
|
* @returns {
|
|
|
* progress 下载进度
|
|
|
* fileSize 文件大小
|
|
@@ -13,63 +13,291 @@ import {ref} from 'vue'
|
|
|
* cancelDownload 取消下载
|
|
|
* }
|
|
|
*/
|
|
|
-export function useDownLoadFile(){
|
|
|
- let progress=ref(0)//进度 0-1
|
|
|
- let fileSize=ref(0)//文件大小
|
|
|
-
|
|
|
- const controller = new AbortController();
|
|
|
-
|
|
|
- // 开始下载
|
|
|
- const startDownload=(url,filename)=>{
|
|
|
- axios({
|
|
|
- url:url,
|
|
|
- method:'get',
|
|
|
- responseType:'blob',
|
|
|
- signal: controller.signal,
|
|
|
- onDownloadProgress:function(progressEvent){
|
|
|
- // console.log(progressEvent);
|
|
|
- fileSize.value=Math.floor(progressEvent.total/1024/1024)
|
|
|
- progress.value = Math.floor(progressEvent.progress*100)
|
|
|
- }
|
|
|
- }).then(res=>{
|
|
|
- // console.log(res);
|
|
|
- const {status,data}=res
|
|
|
- if(status!=200){
|
|
|
- showToast('下载失败')
|
|
|
- return
|
|
|
- }
|
|
|
- const content = data
|
|
|
- const blob = new Blob([content])
|
|
|
- if ('download' in document.createElement('a')) {
|
|
|
- const elink = document.createElement('a')
|
|
|
- elink.download = filename || url.split('/')[url.split('/').length - 1]
|
|
|
- elink.style.display = 'none'
|
|
|
- elink.href = window.URL.createObjectURL(blob)
|
|
|
- document.body.appendChild(elink)
|
|
|
- elink.click()
|
|
|
- window.URL.revokeObjectURL(elink.href)
|
|
|
- document.body.removeChild(elink)
|
|
|
- } else {
|
|
|
- navigator.msSaveBlob(blob, filename)
|
|
|
+export function useDownLoadFile() {
|
|
|
+ let progress = ref(0); //进度 0-1
|
|
|
+ let fileSize = ref(0); //文件大小
|
|
|
+
|
|
|
+ const controller = new AbortController();
|
|
|
+
|
|
|
+ // 开始下载
|
|
|
+ const startDownload = (url, filename) => {
|
|
|
+ axios({
|
|
|
+ url: url,
|
|
|
+ method: "get",
|
|
|
+ responseType: "blob",
|
|
|
+ signal: controller.signal,
|
|
|
+ onDownloadProgress: function (progressEvent) {
|
|
|
+ // console.log(progressEvent);
|
|
|
+ fileSize.value = Math.floor(progressEvent.total / 1024 / 1024);
|
|
|
+ progress.value = Math.floor(progressEvent.progress * 100);
|
|
|
+ },
|
|
|
+ })
|
|
|
+ .then((res) => {
|
|
|
+ // console.log(res);
|
|
|
+ const { status, data } = res;
|
|
|
+ if (status != 200) {
|
|
|
+ showToast("下载失败");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ const content = data;
|
|
|
+ const blob = new Blob([content]);
|
|
|
+ if ("download" in document.createElement("a")) {
|
|
|
+ const elink = document.createElement("a");
|
|
|
+ elink.download = filename || url.split("/")[url.split("/").length - 1];
|
|
|
+ elink.style.display = "none";
|
|
|
+ elink.href = window.URL.createObjectURL(blob);
|
|
|
+ document.body.appendChild(elink);
|
|
|
+ elink.click();
|
|
|
+ window.URL.revokeObjectURL(elink.href);
|
|
|
+ document.body.removeChild(elink);
|
|
|
+ } else {
|
|
|
+ navigator.msSaveBlob(blob, filename);
|
|
|
+ }
|
|
|
+ })
|
|
|
+ .catch((e) => {
|
|
|
+ console.log(e);
|
|
|
+ showToast("下载失败");
|
|
|
+ });
|
|
|
+ };
|
|
|
+
|
|
|
+ //取消下载
|
|
|
+ const cancelDownload = () => {
|
|
|
+ // 取消请求
|
|
|
+ controller.abort();
|
|
|
+ progress.value = 0;
|
|
|
+ fileSize.value = 0;
|
|
|
+ };
|
|
|
+
|
|
|
+ return {
|
|
|
+ fileSize,
|
|
|
+ progress,
|
|
|
+ startDownload,
|
|
|
+ cancelDownload,
|
|
|
+ };
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 下载文件加水印
|
|
|
+ */
|
|
|
+export function useDownLoadFileAddWaterMark() {
|
|
|
+ let progress = ref(0); //进度 0-1
|
|
|
+ let fileSize = ref(0); //文件大小
|
|
|
+
|
|
|
+ const controller = new AbortController();
|
|
|
+
|
|
|
+ // 获取水印图片数据
|
|
|
+ function getWaterMark(str) {
|
|
|
+ return new Promise((resolve, reject) => {
|
|
|
+ const text = str || ""; // 默认水印文字
|
|
|
+ const canvas = document.createElement("canvas");
|
|
|
+
|
|
|
+ // 设置canvas尺寸,增加分辨率
|
|
|
+ const canvasWidth = 800;
|
|
|
+ const canvasHeight = 400;
|
|
|
+ canvas.width = canvasWidth;
|
|
|
+ canvas.height = canvasHeight;
|
|
|
+
|
|
|
+ const ctx = canvas.getContext("2d");
|
|
|
+
|
|
|
+ // 增大字体尺寸并设置样式
|
|
|
+ ctx.font = "50px Arial"; // 字体大小
|
|
|
+ ctx.textAlign = "center"; // 水平居中
|
|
|
+ ctx.textBaseline = "middle"; // 垂直居中
|
|
|
+ ctx.fillStyle = "#333"; // 水印文字颜色
|
|
|
+ ctx.globalAlpha = 0.1; // 水印透明度,避免过于显眼
|
|
|
+
|
|
|
+ ctx.translate(canvasWidth / 2, canvasHeight / 2); // 移动到中心
|
|
|
+ ctx.rotate((-45 * Math.PI) / 200); // 旋转 -45 度
|
|
|
+ ctx.fillText(text, 0, 0); // 在旋转后的中心绘制文字
|
|
|
+
|
|
|
+ // 将canvas内容转换为base64编码的PNG图片
|
|
|
+ const data = canvas.toDataURL("image/png");
|
|
|
+ resolve(data);
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ // 辅助方法:将 Blob 转换为 ArrayBuffer
|
|
|
+ function blobToArrayBuffer(blob) {
|
|
|
+ return new Promise((resolve, reject) => {
|
|
|
+ const reader = new FileReader();
|
|
|
+ reader.onload = () => resolve(reader.result);
|
|
|
+ reader.onerror = (error) => reject(error);
|
|
|
+ reader.readAsArrayBuffer(blob);
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 开始下载
|
|
|
+ * @param type pdf img
|
|
|
+ * @returns
|
|
|
+ */
|
|
|
+ const startDownload = async ({ url, filename, waterMark, type }) => {
|
|
|
+ try {
|
|
|
+ const res = await axios({
|
|
|
+ url: url,
|
|
|
+ method: "get",
|
|
|
+ responseType: "blob",
|
|
|
+ signal: controller.signal,
|
|
|
+ onDownloadProgress: function (progressEvent) {
|
|
|
+ // console.log(progressEvent);
|
|
|
+ fileSize.value = Math.floor(progressEvent.total / 1024 / 1024);
|
|
|
+ progress.value = Math.floor(progressEvent.progress * 100);
|
|
|
+ },
|
|
|
+ });
|
|
|
+ // console.log(res);
|
|
|
+ const { status, data } = res;
|
|
|
+ if (status != 200) {
|
|
|
+ showToast("下载失败");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ const blob = new Blob([data]);
|
|
|
+ // 不需要水印
|
|
|
+ if (!waterMark) {
|
|
|
+ if ("download" in document.createElement("a")) {
|
|
|
+ const elink = document.createElement("a");
|
|
|
+ elink.download = filename || url.split("/")[url.split("/").length - 1];
|
|
|
+ elink.style.display = "none";
|
|
|
+ elink.href = window.URL.createObjectURL(blob);
|
|
|
+ document.body.appendChild(elink);
|
|
|
+ elink.click();
|
|
|
+ window.URL.revokeObjectURL(elink.href);
|
|
|
+ document.body.removeChild(elink);
|
|
|
+ } else {
|
|
|
+ navigator.msSaveBlob(blob, filename);
|
|
|
+ }
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (type === "pdf") {
|
|
|
+ // 加载 PDF 文档 将 blob 转化为 `string` or `Uint8Array` or `ArrayBuffer`
|
|
|
+ const pdfBytes = await blobToArrayBuffer(blob); // 将 Blob 转为 ArrayBuffer
|
|
|
+ const pdfDoc = await PDFDocument.load(pdfBytes);
|
|
|
+ const pages = pdfDoc.getPages();
|
|
|
+
|
|
|
+ // 获取水印图像
|
|
|
+ const watermarkImageData = await getWaterMark(waterMark);
|
|
|
+ const watermarkImage = await pdfDoc.embedPng(watermarkImageData);
|
|
|
+
|
|
|
+ pages.forEach(page => {
|
|
|
+ const { width, height } = page.getSize();
|
|
|
+
|
|
|
+ // 水印图像的大小 (适应页面大小并保持比例)
|
|
|
+ const imageWidth = width / 5; // 水印宽度为页面宽度的1/5
|
|
|
+ const imageHeight = watermarkImage.height * (imageWidth / watermarkImage.width);
|
|
|
+
|
|
|
+ // 设置水印透明度
|
|
|
+ const opacity = 1; // 控制透明度
|
|
|
+
|
|
|
+ // 计算水印重复的个数
|
|
|
+ const cols = Math.ceil(width / imageWidth); // 水印在水平方向的个数
|
|
|
+ const rows = Math.ceil(height / imageHeight); // 水印在垂直方向的个数
|
|
|
+
|
|
|
+ // 在页面上绘制水印(按格子重复)
|
|
|
+ for (let row = 0; row < rows; row++) {
|
|
|
+ for (let col = 0; col < cols; col++) {
|
|
|
+ const x = col * imageWidth;
|
|
|
+ const y = row * imageHeight;
|
|
|
+
|
|
|
+ page.drawImage(watermarkImage, {
|
|
|
+ x: x,
|
|
|
+ y: y,
|
|
|
+ width: imageWidth,
|
|
|
+ height: imageHeight,
|
|
|
+ opacity: opacity, // 设置透明度
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ // 导出加水印后的 PDF
|
|
|
+ const modifiedPdfBytes = await pdfDoc.save();
|
|
|
+ const blobRes = new Blob([modifiedPdfBytes], { type: 'application/pdf' });
|
|
|
+ if ('download' in document.createElement('a')) {
|
|
|
+ const elink = document.createElement('a');
|
|
|
+ elink.download = filename || url.split("/")[url.split("/").length - 1];
|
|
|
+ elink.style.display = 'none';
|
|
|
+ elink.href = window.URL.createObjectURL(blobRes);
|
|
|
+ document.body.appendChild(elink);
|
|
|
+ elink.click();
|
|
|
+ window.URL.revokeObjectURL(elink.href);
|
|
|
+ document.body.removeChild(elink);
|
|
|
+ } else {
|
|
|
+ navigator.msSaveBlob(blobRes, filename);
|
|
|
+ }
|
|
|
+
|
|
|
+ } else if (type === "img") {
|
|
|
+ // 处理图片加水印
|
|
|
+ const img = new Image();
|
|
|
+ img.src = URL.createObjectURL(blob);
|
|
|
+
|
|
|
+ img.onload = async () => {
|
|
|
+ // 创建canvas并绘制图片
|
|
|
+ const canvas = document.createElement("canvas");
|
|
|
+ const ctx = canvas.getContext("2d");
|
|
|
+ canvas.width = img.width;
|
|
|
+ canvas.height = img.height;
|
|
|
+
|
|
|
+ // 绘制原始图片
|
|
|
+ ctx.drawImage(img, 0, 0, img.width, img.height);
|
|
|
+
|
|
|
+ // 获取水印图像
|
|
|
+ const watermarkImageData = await getWaterMark(waterMark);
|
|
|
+ const watermarkImg = new Image();
|
|
|
+ watermarkImg.src = watermarkImageData;
|
|
|
+
|
|
|
+ watermarkImg.onload = () => {
|
|
|
+ const watermarkWidth = img.width / 5; // 设置水印宽度
|
|
|
+ const watermarkHeight = (watermarkImg.height / watermarkImg.width) * watermarkWidth; // 计算水印高度,保持比例
|
|
|
+
|
|
|
+ // 计算水印的重复个数
|
|
|
+ const cols = Math.ceil(img.width / watermarkWidth); // 水印在水平方向的个数
|
|
|
+ const rows = Math.ceil(img.height / watermarkHeight); // 水印在垂直方向的个数
|
|
|
+
|
|
|
+ // 绘制水印
|
|
|
+ for (let row = 0; row < rows; row++) {
|
|
|
+ for (let col = 0; col < cols; col++) {
|
|
|
+ const x = col * watermarkWidth;
|
|
|
+ const y = row * watermarkHeight;
|
|
|
+ ctx.drawImage(watermarkImg, x, y, watermarkWidth, watermarkHeight);
|
|
|
+ }
|
|
|
}
|
|
|
- }).catch((e)=>{
|
|
|
- console.log(e);
|
|
|
- showToast('下载失败')
|
|
|
- })
|
|
|
- }
|
|
|
|
|
|
- //取消下载
|
|
|
- const cancelDownload=()=>{
|
|
|
- // 取消请求
|
|
|
- controller.abort()
|
|
|
- progress.value=0
|
|
|
- fileSize.value=0
|
|
|
+ // 导出加水印后的图片
|
|
|
+ canvas.toBlob((modifiedBlob) => {
|
|
|
+ const blobRes = modifiedBlob;
|
|
|
+ if ("download" in document.createElement("a")) {
|
|
|
+ const elink = document.createElement("a");
|
|
|
+ elink.download = filename || url.split("/")[url.split("/").length - 1];
|
|
|
+ elink.style.display = "none";
|
|
|
+ elink.href = window.URL.createObjectURL(blobRes);
|
|
|
+ document.body.appendChild(elink);
|
|
|
+ elink.click();
|
|
|
+ window.URL.revokeObjectURL(elink.href);
|
|
|
+ document.body.removeChild(elink);
|
|
|
+ } else {
|
|
|
+ navigator.msSaveBlob(blobRes, filename);
|
|
|
+ }
|
|
|
+ }, "image/png");
|
|
|
+ };
|
|
|
+ };
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ showToast("下载失败,请稍后重试");
|
|
|
}
|
|
|
+ };
|
|
|
|
|
|
- return {
|
|
|
- fileSize,
|
|
|
- progress,
|
|
|
- startDownload,
|
|
|
- cancelDownload
|
|
|
- }
|
|
|
-}
|
|
|
+ //取消下载
|
|
|
+ const cancelDownload = () => {
|
|
|
+ // 取消请求
|
|
|
+ controller.abort();
|
|
|
+ progress.value = 0;
|
|
|
+ fileSize.value = 0;
|
|
|
+ };
|
|
|
+
|
|
|
+ return {
|
|
|
+ fileSize,
|
|
|
+ progress,
|
|
|
+ startDownload,
|
|
|
+ cancelDownload,
|
|
|
+ };
|
|
|
+}
|