.net core 微服务下的手工签名实现,以及消除中文乱码
最近在實現一款業主簽字的需求,簽字前端由vue下的某個共享組件實現,其采用Canvas繪圖方式實現簽名圖片的生成,后臺主要提供簽名前文檔的呈現,以及簽名后文件合成過的簽名文檔保存。
FastReport
報表生成器FastReport .NET是適用于.NET Core 3,ASP.NET,MVC和Windows窗體的全功能報告庫。使用FastReport .NET,您可以創建獨立于應用程序的.NET報告。
想當年水晶報表爆火全網,而今已不見身影,目前最好用的.net 平臺的報表莫過于FastReport,購買正版也不是那么貴,對于企業客戶來說,簡單易用。
基于上述諸多特點,我們選用了FastReport產品作為報表的基礎。其擁有強大的可視化報表設計器,可用于創建和修改報表。可以連接到任何數據庫,使用其任何表或創建查詢。最關鍵的是基于linux下打印輸出性能較好,在過去的幾個版本曾經有過內存溢出現象,目前基本完美解決。因此企業客戶可以優先選擇了。
中文亂碼的解決
中文亂碼,嚴格意義上不屬于FastReport的問題,其是我們在裁剪linux下,缺少中文字體所致,因此需要安裝中文字體即可。
以下是docker容器下的安裝命令
COPY ./fonts/ /usr/share/fonts/哈哈,這里偷了個懶,直接把我需要的fonts包含在項目內,發布時拷貝過去即可。
當然還有另外的安裝方法,我沒有嘗試。
當然你也必須安裝gdiplus,這是大前提,參考如下代碼:
RUN yum -y install .. libc6-dev libgdiplus ..&& yum clean allRUN ln -s /usr/lib64/libdl.so.2 /usr/lib64/libdl.soRUN ln -s /usr/lib64/libgdiplus.so.0.0.0 /usr/lib64/libgdiplus.so在線手工簽名的實現思路
實現的思路如下,一圖勝千言。
Canvas
后臺api
生成
手工簽名
簽字圖片
保存路徑
數據源
FastReport 報表
xml報表模板
輸出圖片或PDF
FastReport的模板
模板文件可以采用設計器設計,設計完后,稍微修改下datasource,修改后的模板文件如下,供參考:
<?xml version="1.0" encoding="utf-8"?> <Report ScriptLanguage="CSharp" ReportInfo.Created="02/20/2017 23:01:52" ReportInfo.Modified="09/24/2020 10:59:37" ReportInfo.CreatorVersion="2019.3.26.0"><ScriptText> using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Windows.Forms; using System.Drawing; using System.Data; using FastReport; using FastReport.Data; using FastReport.Dialog; using FastReport.Barcode; using FastReport.Table; using FastReport.Utils;namespace FastReport {public class ReportScript{} }</ScriptText><Dictionary><TableDataSource Name="t1" ReferenceName="Data.Table1" DataType="System.Int32" Enabled="true"> <Column Name="HOUSE_GID" DataType="System.String"/><Column Name="GOODS_NAME" DataType="System.String"/><Column Name="GOODS_STATUS" DataType="System.String"/><Column Name="GOODS_DESCRIBE" DataType="System.String"/><Column Name="CID" DataType="System.String"/><Column Name="GOODS_NUMBER" DataType="System.Int16"/></TableDataSource><TableDataSource Name="t2" ReferenceName="Data.Table2" DataType="System.Int32" Enabled="true"> <Column Name="FILE_ID" DataType="System.String"/></TableDataSource></Dictionary><ReportPage Name="Page1" Watermark.Font="宋體, 60pt"><PageHeaderBand Name="PageHeader1" Width="718.2" Height="85.05"><PictureObject Name="Picture1" Left="9.45" Width="349.65" Height="66.15" Image=""/><TextObject Name="txtTitle" Left="478.95" Top="18.9" Width="302.4" Height="47.25" Text="收房確認書" HorzAlign="Center" Font="宋體, 20pt"/><LineObject Name="Line1" Left="6.45" Top="66.15" Width="689.85"/></PageHeaderBand><DataBand Name="Data1" Top="338.75" Width="718.2" Height="37.8" CanGrow="true" CanShrink="true"><TextObject Name="Text36" Left="25.35" Width="47.25" Height="28.35" Border.Lines="All" CanGrow="true" GrowToBottom="true" Text="[Row#]" HorzAlign="Center" VertAlign="Center" Font="宋體, 9pt"/><TextObject Name="Text32" Left="72.6" Width="132.3" Height="28.35" Border.Lines="All" CanGrow="true" GrowToBottom="true" Text="[t1.GOODS_NAME]" HorzAlign="Center" VertAlign="Center" WordWrap="false" Font="宋體, 9pt"/><TextObject Name="Text111" Left="204.9" Width="132.3" Height="28.35" Border.Lines="All" CanGrow="true" GrowToBottom="true" Text="[t1.GOODS_NUMBER]" HorzAlign="Center" VertAlign="Center" WordWrap="false" Font="宋體, 9pt"/><TextObject Name="Text31" Left="337.2" Width="270.27" Height="28.35" Border.Lines="All" CanGrow="true" GrowToBottom="true" Text="[t1.GOODS_DESCRIBE]" VertAlign="Center" Font="宋體, 9pt"/><DataHeaderBand Name="DataHeader1" Top="89.05" Width="718.2" Height="245.7"><TextObject Name="Text18" Left="25.35" Top="217.35" Width="47.25" Height="28.35" Border.Lines="All" Text="行號" HorzAlign="Center" VertAlign="Center" Font="宋體, 9pt"/><TextObject Name="Text9" Left="72.6" Top="217.35" Width="132.3" Height="28.35" Border.Lines="All" Text="物品" HorzAlign="Center" VertAlign="Center" Font="宋體, 9pt"/><TextObject Name="Text8" Left="337.2" Top="217.35" Width="270.27" Height="28.35" Border.Lines="All" Text="物品描述" HorzAlign="Center" VertAlign="Center" Font="宋體, 9pt"/><TextObject Name="Text110" Left="204.9" Top="217.35" Width="132.3" Height="28.35" Border.Lines="All" Text="數量" HorzAlign="Center" VertAlign="Center" Font="宋體, 9pt"/><TextObject Name="lblVendorName" Left="6.45" Top="56.7" Width="689.85" Height="132.3" Text="高科房地產開發有限公司和業主就『東方現代城』第?? 房向業主進行交接。 ?1、業主已檢查清楚物業全部自用部位和自用設備,并已掌握室內設施的正確使用方法。 ?2、業主在此確認,已收到該物業的相關物件:" VertAlign="Center" Font="宋體, 9pt"/><TextObject Name="Text113" Left="186" Top="9.45" Width="302.4" Height="47.25" Text="收房確認書" HorzAlign="Center" Font="宋體, 20pt"/><TextObject Name="Text1" Left="302.4" Top="85.05" Width="122.85" Height="18.9" Text="[house_handover_goods.HOUSE_GID]" Font="宋體, 14pt"/></DataHeaderBand><DataFooterBand Name="DataFooter1" Top="380.55" Width="718.2" Height="160.65"><TextObject Name="Text109" Left="6.45" Top="9.45" Width="689.85" Height="151.2" Text=" 3、室內全部設施驗收合格。? 4、本人已簽署之東方現代城《前期物業管理服務協議》、《業主臨時管理規約》、《消防安全責任書》和領取《業戶手冊》、《裝修手冊》、《住宅質量保證書》、《住宅使用說明書》等全部資料,并已完全了解以上內容,愿意接受相關服務及遵守東方現代城夷各項管理規定,并鄭重承諾:? 本人及房屋使用人、承租人、受讓人等遵守上述規定相關條款,承擔違反上述規定所造成的一切責任和損失。? 如果轉讓本物業,本人承諾將上述資料轉予受讓人,并將轉讓事宜自轉讓合同簽署之日起10日內書面通知物業服務企業。" VertAlign="Center" Font="宋體, 9pt"/></DataFooterBand></DataBand><PageFooterBand Name="PageFooter1" Top="545.2" Width="718.2" Height="132.3"><TextObject Name="txtPrintDate" Left="186" Top="94.5" Width="122.85" Height="18.9" Text="[Date]" Font="宋體, 9pt"/><TextObject Name="Text3" Left="72.6" Top="94.5" Width="85.05" Height="18.9" Text="簽字日期:" Font="宋體, 9pt"/><TextObject Name="Text112" Left="72.6" Top="18.9" Width="85.05" Height="18.9" Text="業主簽字:" Font="宋體, 9pt"/><PictureObject Name="Picture2" Left="217.35" Top="9.45" Width="359.1" Height="75.6" ImageLocation="http://192.168.1.6/api/file/85074023914016768"/></PageFooterBand></ReportPage> </Report>導出pdf代碼
FastReport導出pdf代碼比較精簡,如下:
FastReport.Report report = new FastReport.Report();report.RegisterData(ds);// 這里是下載模板文件using (MemoryStream stream = Tools.DownLoad(fpxPath, context)){report.Load(stream);}report.Prepare();return report; PDFExport export = new PDFExport(); export.SetReport(report); export.Compressed = true; export.Background = false; export.PrintOptimized = false; export.OpenAfterExport = false; export.EmbeddingFonts = true; fileName = getTempFilePath("pdf"); report.Export(export, fileName);導出pdf,一切完美,但是由于簽名后無法在手機端呈現pdf,因此只能把其導出為圖片了,重點來了,生成的圖片亂碼了@#¥#@%¥#%¥……%¥
導出圖片
導出 圖片代碼如下,替換pdfexport即可:
var exportPng = new ImageExport(); exportPng.ImageFormat = ImageExportFormat.Png; exportPng.SetReport(report); exportPng.OpenAfterExport = false; fileName = getTempFilePath("png"); report.Export(exportPng, fileName);
好慘啊,為甚這樣對我?PDF生成就是好的啊,圖片為啥亂碼呢,難道centos下仍然需要安裝其他東東?
亂碼解決
進入Docker容器,各種字體庫一頓猛如虎的操作,再次導出,毛用沒有起到,仍然是尷尬的亂碼。到底哪里出問題了?
開啟神器搜索之王,一通搜索,找到了一篇issue:?https://github.com/dotnet/runtime/issues/30941,這個bug闡述說.net core2.2可以繪制出好的文字,而.net core 3.0缺出現了bug,難道我這個問題和它們是相似的?
微軟的專家說問題的原因是,他們已經在3.1修復了bug:
This was broken as part of this change: dotnet/corefx@b75421a#diff-8eda13b1268284d720355f95667dea21R218 as it is missing a CharSet = Unicode parameter in the DllImport.
Then we consolidated some Graphics code in between Unix and Windows and this was fixed there as you can see on master:
https://github.com/dotnet/corefx/blob/b49a8a9be1d53cd9e50cb68fd8540be25c65d433/src/System.Drawing.Common/src/System/Drawing/GdiplusNative.cs#L1234
I will put up a PR to fix this on 3.0 and 3.1 and of course audit to see if there were any other regressions where we needed to use Unicode as the Charset.
意思就是在引用 dll時,沒有加 CharSet = CharSet.Unicode,好吧,這個人好粗心!哈哈~~~~
[DllImport(LibraryName, ExactSpelling = true, CharSet = CharSet.Unicode)]internal static extern int GdipDrawString(HandleRef graphics, string textString, int length, HandleRef font, ref RectangleF layoutRect, HandleRef stringFormat, HandleRef brush);大致找到了問題,那就簡單了。我們為微服務項目內引用最新的包,相信應該可以搞定了。
<PackageReference Include="Microsoft.CodeAnalysis" Version="3.7.0" /> <PackageReference Include="System.Drawing.Common" Version="4.7.0" /> <PackageReference Include="System.Text.Encoding.CodePages" Version="4.7.1" />修改,發布,測試,哈哈,搞定!
簽名圖片嵌入:采用url方式嵌入,需要在模板內編寫代碼。
結語
又是一上午的時間,報表模板編輯,亂碼,程序員的時間就是這么背消磨完的。希望這篇文章能幫助到你,使得你能節省出大量的時間,早早的回家陪家人!
FastReport真心好用,它已經節省了我大量的時間。如果能把亂碼處理好,那應該不會再有大的坑了!
總結
以上是生活随笔為你收集整理的.net core 微服务下的手工签名实现,以及消除中文乱码的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 为啥 .NET 自带的 JsonSeri
- 下一篇: 使用Blazor开发内部后台(一):认识