在日常工作中,我們常常需要將SVG轉換為PDF格式。這是因為SVG格式的圖像在列印時可能會出現問題,例如失去解析度或無法正確適應紙張大小。與此相比,PDF格式則專門用於列印和共用文檔,可以確保高質量輸出,並且能夠自動適應不同的紙張大小。在本文中,我們將介紹如何使用編程方式將SVG文件轉換為PDF,並... ...
前言:我這裡文件下載的模板選型優先考慮html模板,上手容易,前後端通用,有了模板後就需要有轉換了,html轉PDF採用第三方包:SelectPdf,下麵是代碼核心類:
1-PDFService:
using Microsoft.AspNetCore.Hosting; using SelectPdf; namespace MeShop.Domain.PDF { /// <summary> /// PDF業務類 /// </summary> public class PDFService { private readonly IHostingEnvironment hostingEnvironment; public PDFService(IHostingEnvironment hostingEnvironment) { this.hostingEnvironment = hostingEnvironment; } /// <summary> /// 將Html替換參數後轉成PDF位元組流 /// </summary> /// <param name="htmlFilePath">html模板文件路徑</param> /// <param name="saveFileName">PDF文件名</param> /// <param name="replaceParamDic">變數替換字典</param> /// <returns></returns> public async Task<string> HtmlToPDFFile(string htmlFilePath, string saveFileName, Dictionary<string, string> replaceParamDic) { HtmlToPdf Renderer = new HtmlToPdf(); //設置Pdf參數 //設置頁面方式-橫向 PdfPageOrientation.Portrait 豎向 Renderer.Options.PdfPageOrientation = PdfPageOrientation.Landscape; //設置頁面大小,30種頁面大小可以選擇 Renderer.Options.PdfPageSize = PdfPageSize.A4; //上下左右邊距設置 Renderer.Options.MarginTop = 10; Renderer.Options.MarginBottom = 10; Renderer.Options.MarginLeft = 10; Renderer.Options.MarginRight = 10; //設置更多額參數可以去HtmlToPdfOptions裡面選擇設置 //根據html內容導出PDF string docHtml = await File.ReadAllTextAsync(htmlFilePath, Encoding.UTF8); foreach (var item in replaceParamDic) { docHtml = docHtml.Replace(item.Key, item.Value); } PdfDocument pdfDocument = Renderer.ConvertHtmlString(docHtml); string saveFilePath = @$"{this.hostingEnvironment.ContentRootPath}\staticfiles\Download\{saveFileName}"; if (File.Exists(saveFilePath)) { File.Delete(saveFilePath); } pdfDocument.Save(saveFilePath); return saveFilePath; } /// <summary> /// 讀取文件位元組流 /// </summary> /// <param name="filePath">資源文件(包含路徑)</param> /// <param name="isDeleteSourceFile">是否刪除資源文件</param> /// <returns></returns> public async Task<byte[]> GetByteByFile(string? filePath, bool isDeleteSourceFile = false) { byte[]? myByteArray = null; if (filePath != null && File.Exists(filePath)) { using (FileStream fileStream = new FileStream(filePath, FileMode.Open)) { fileStream.Seek(0, SeekOrigin.Begin); myByteArray = new byte[fileStream.Length]; await fileStream.ReadAsync(myByteArray, 0, (int)fileStream.Length); } if (isDeleteSourceFile) { File.Delete(filePath); } } return myByteArray ?? new byte[0]; } /// <summary> /// 壓縮多個文件為zip文件 /// </summary> /// <param name="zipFileName">zip壓縮文件名</param> /// <param name="filePaths">資源文件列表(包含路徑)</param> /// <param name="isDeleteSourceFile">是否刪除資源文件</param> /// <returns></returns> public string CompressFileToZip(string zipFileName, string[] filePaths, bool isDeleteSourceFile = false) { string? zipFilePath = null; if (!string.IsNullOrWhiteSpace(zipFileName) && filePaths.Length > 0) { string zipDirectoryPath = @$"{this.hostingEnvironment.ContentRootPath}\staticfiles\Download\{DateTime.Now.ToString("yyyyMMddHHmmssfff")}"; if (!Directory.Exists(zipDirectoryPath)) { Directory.CreateDirectory(zipDirectoryPath); } zipFilePath = @$"{this.hostingEnvironment.ContentRootPath}\staticfiles\Download\{zipFileName}"; if (File.Exists(zipFilePath)) { File.Delete(zipFilePath); } foreach (var filePath in filePaths) { string? fileName = filePath.Split('\\').LastOrDefault(); string copyFilePath = @$"{zipDirectoryPath}\{fileName}"; if (isDeleteSourceFile) { File.Move(filePath, copyFilePath); } else { File.Copy(filePath, copyFilePath); } } CompressionHelper.Compression(zipDirectoryPath, zipFilePath); //壓縮完成後,刪除壓縮使用文件夾及其子項 Directory.Delete(zipDirectoryPath, true); } return zipFilePath ?? ""; } } }
2-控制器方法示例:
[HttpGet("DownloadSettlement")] public async Task<JsonModel<byte[]>> DownloadSettlement(string settlementIDS) { byte[]? byteArray = null; string[] settlementIDArray = settlementIDS.Split(','); string templateHtmlPath = @$"{this.hostingEnvironment.ContentRootPath}\staticfiles\agentusersettlement.html"; List<string> zipSaveFilePathList = new List<string>(settlementIDArray.Length); Base_shop baseShop = await this.shopService.GetBaseShopAsync(); foreach (var item in settlementIDArray) { long settlementID = TypeParseHelper.StrToInt64(item); ResponseAgentUserSettlementDetail? detail = await this.agentUserSettlementService.GetDetailAsync(settlementID); if (detail != null) { Agent_user agentUser = await this.agentUserService.GetAsync(detail.AgentUserID) ?? new Agent_user(); Dictionary<string, string> replaceDic = new Dictionary<string, string>() { {"@InvoiceNumber@",$"{detail.UpdateTime.ToString("yyyyMMdd")}{detail.ID}" }, {"@UpdateTime@",$"{detail.UpdateTime.ToString("yyyyMMdd")}" }, {"@AgentUserCompanyName@",$"{agentUser.CompanyName}" }, {"@AgentUserCompanyAddress@",$"{agentUser.CompanyAddress}" }, {"@BeginDate@",$"{detail.BeginDate.ToString("yyyy/MM/dd")}" }, {"@EndDate@",$"{detail.EndDate.ToString("yyyy/MM/dd")}" }, {"@TotalPoint@",$"{detail.TotalPoint.ToString("F3")}" }, {"@AccountCompanyName@",$"{baseShop.CompanyName}" }, {"@AccountCompanyAddress@",$"{baseShop.CompanyAddress}" }, {"@AccountEmail@",$"{baseShop.ServiceEmail}" } }; zipSaveFilePathList.Add(await this.pdfService.HtmlToPDFFile(templateHtmlPath, $"{settlementID}.pdf", replaceDic)); //設置導出狀態 await this.agentUserSettlementService.SetExportStateAsync(settlementID, (int)EState.啟用); } } if (zipSaveFilePathList.Count == 1) { byteArray = await this.pdfService.GetByteByFile(zipSaveFilePathList.FirstOrDefault()); } else { string zipFilePath = this.pdfService.CompressFileToZip($"{settlementIDS.Replace(',', '_')}.zip", zipSaveFilePathList.ToArray(), true); byteArray = await this.pdfService.GetByteByFile(zipFilePath); } return base.SuccessResult(byteArray ?? new byte[0]); }
3-前臺JS下載文件位元組流示例:
<script> var dataURLtoBlob = function (baseData, dataFileType) { var bstr = atob(baseData) var n = bstr.length; var u8arr = new Uint8Array(n); while (n--) { u8arr[n] = bstr.charCodeAt(n); } return new Blob([u8arr], { type: dataFileType }); }; var dataByteArray = "後臺方法返回的文件位元組流數據" var dataIsZip = true; var dataIsPDF = false var fileName = null; var blob = null; if (dataIsZip) { blob = dataURLtoBlob(dataByteArray, "application/zip; charset=utf-8"); fileName = "test.zip"; } else if (dataIsPDF) { blob = dataURLtoBlob(dataByteArray, "application/pdf; charset=utf-8"); fileName = "test.pdf"; } var url = window.URL.createObjectURL(blob); var a = document.createElement('a'); a.href = url; a.download = fileName; a.click(); window.URL.revokeObjectURL(url); </script>
*感謝您的閱讀。喜歡的、有用的就請大哥大嫂們高抬貴手“推薦一下”吧!你的精神 支持是博主強大的寫作動力。歡迎轉載!
*博主的文章是自己平時開發總結的經驗,由於博主的水平不高,不足和錯誤之處在所難免,希望大家能夠批評指出。
*我的博客: http://www.cnblogs.com/lxhbky/