.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包含在项目内,发布时拷贝过去即可。
当然还有另外的安装方法,我没有尝试。

#向容器安装中文编码支持
RUN  yum -y install kde-l10n-Chinese telnet && \  yum -y reinstall glibc-common &&\  yum clean all  && \  localedef -c -f UTF-8 -i zh_CN zh_CN.utf8   #设置容器编码格式
ENV LC_ALL "zh_CN.UTF-8"  

当然你也必须安装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="高科房地产开发有限公司和业主就『东方现代城』第                       房向业主进行交接。&#13;&#10;&#13;&#10; 1、业主已检查清楚物业全部自用部位和自用设备,并已掌握室内设施的正确使用方法。&#13;&#10;&#13;&#10; 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="&#13;&#10; 3、室内全部设施验收合格。 &#13;&#10;&#13;&#10; 4、本人已签署之东方现代城《前期物业管理服务协议》、《业主临时管理规约》、《消防安全责任书》和领取《业户手册》、《装修手册》、《住宅质量保证书》、《住宅使用说明书》等全部资料,并已完全了解以上内容,愿意接受相关服务及遵守东方现代城夷各项管理规定,并郑重承诺: &#13;&#10;&#13;&#10;     本人及房屋使用人、承租人、受让人等遵守上述规定相关条款,承担违反上述规定所造成的一切责任和损失。 &#13;&#10;     如果转让本物业,本人承诺将上述资料转予受让人,并将转让事宜自转让合同签署之日起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方式嵌入,需要在模板内编写代码。

//<Parameter Name="signUri" DataType="System.String" Expression="&quot;http://192.168.1.6/api/file/&quot;+[t2.FILE_ID]"/>private void Picture2_BeforePrint(object sender, EventArgs e){Picture2.ImageLocation = (string)Report.GetParameterValue("signUri")  ;}

结语

又是一上午的时间,报表模板编辑,乱码,程序员的时间就是这么背消磨完的。希望这篇文章能帮助到你,使得你能节省出大量的时间,早早的回家陪家人!

FastReport真心好用,它已经节省了我大量的时间。如果能把乱码处理好,那应该不会再有大的坑了!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/300709.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

高性能通道

高性能通道 http://detail.1688.com/offer/896868540.html https://www.datastoragecables.com/qsfp/qsfp-qsfp/qsfp-qsfp-ib/C9494-M-IB.html【infiniband】 http://pkg-ofed.alioth.debian.org/howto/infiniband-howto.html#toc6【infiniband-ib】posted on 2013-10-28 21:26…

清华学霸直博简历火了!CPU、操作系统、编译器全自主写,刘知远点赞

全世界只有3.14 % 的人关注了青少年数学之旅清华大学直博面试的一则简历上了知乎热榜&#xff1a;“实现了在自己写的CPU上运行自己写的操作系统&#xff0c;以及自己实现的编译器生成的程序”。简历主人是清华计算机系本科生周聿浩同学&#xff0c;他顺利拿到直博名额&#xf…

使用Blazor开发内部后台(一):认识Blazor

转载技术社区中一位朋友最新的文章&#xff0c;介绍自己为公司的 WebForm 遗留系统使用 Blazor 重写前端 UI 的经历。前言啊&#xff0c;又好久没写文章了&#xff0c;这一年一直在接触新的领域&#xff0c;扩展了一下技术面&#xff0c;学了很多新东西。前阵子发现公司内部有个…

全球科技界最鼓舞人心领袖揭晓!马斯克第一,马云第五

全世界只有3.14 % 的人关注了青少年数学之旅谁是科技界最鼓舞人心的领袖&#xff1f;最近技术招聘网站Hired对3600多名技术人员进行了调查&#xff0c;最终马斯克击败贝佐斯、纳德拉、扎克伯格等人成功当选&#xff0c;马云排名第五。SpaceX被评为全球私人公司中第二大最受欢迎…

设置mysql表myisam_mysql myisam 优化设置设置

mysql myisam 优化设置设置更新时间&#xff1a;2010年03月16日 21:28:24 作者&#xff1a;mysql myisam 优化设置设置&#xff0c;需要的朋友可以参考下。myisam_max_[extra]_sort_file_size足够大delay_key_write减少io,提高写入性能bulk_insert_buffer_sizeconcurrent_ins…

NET问答: 为什么 String.IndexOf 在 .net5 和 netcore3 中返回值不一样?

咨询区 Farhad Zamani&#xff1a;当我在 .NET Core 3.1 中运行下面代码的时候&#xff0c;程序会返回 6。class Program{static void Main(string[] args){// .NET Core 3.1string s "Hello\r\nworld!";int idx s.IndexOf("\n");Console.WriteLine(idx)…

vSpere虚拟网卡介绍

在一个物理网络拓扑中&#xff0c;通常都是路由器-交换机-PC机的连接&#xff0c;不同的服务器和PC机&#xff0c;通过交换机的连接而相互连通。在VMwarevSphere架构下服务器会虚拟出交换机来供ESXHost虚拟机来使用&#xff0c;虚拟交换机有两种&#xff0c;vSwitch虚拟交换机和…

快速掌握MATLAB应用,只要从这一步开始!

有人说&#xff0c;“MATLAB除了不会生孩子&#xff0c;什么都会。”矩阵运算、数据可视化、GUI&#xff08;用户界面&#xff09;设计、甚至是连接其他编程语言&#xff0c;MATLAB都能轻松实现&#xff01;那么&#xff0c;MATLAB到底有多厉害&#xff1f;MATLAB拥有丰富的算法…

如何查看 .NET Core 3.1 源代码

背景在 .NET 走向开源后&#xff0c;我们可以方便的查看 .NET 内部的实现方式&#xff0c;学习和寻找问题&#xff0c;甚至参与到 .NET 的开发中。前段时间&#xff0c;同事需要查看 C# 的 Task 类 (System.Threading.Tasks) 的一些实现和内部的原理&#xff0c;想找 Task 类的…

装×失败的后果。。。 | 今日最佳

世界只有3.14 % 的人关注了青少年数学之旅传说中的“虎口夺食”摄像头留下了垃圾桶欺负我的证据用力过猛扯淡还是扯底裤装失败二进洗脚盆玻璃太干净了&#xff0c;注意左边这个傻子哎呀&#xff0c;这个傻子真的是傻中奖的感觉还是要量力而行滑的还真溜。。。电动车此刻注入了灵…

.net core 下的HttpClient、WebClient性能测试

有许多服务需要拉取api接口数据&#xff0c;因此后端开发少不了对Http访问请求进行封装&#xff0c;最主要的应用方式莫过于采用WebClient进行封装&#xff0c;简单易用&#xff1b;而.net core微软官方推荐的是HttpClient和HttpClientFactory&#xff0c;到底哪个性能更加强劲…

北京一公交车发生爆炸 疑为乘客携带药品起反应

勘察人员从公交车里取出可疑爆炸物。薛珺摄点击查看其它图片昨日下午&#xff0c;一辆850路公交车行驶在阜成路时发生爆炸。5名乘客经检查均无大碍。   警方怀疑是乘客所携类似血清的药品引发化学反应所致。   事故现场在八里庄桥上&#xff0c;昨日下午5时许&#xff0c;一…

给定两个二叉树T和S,判断S是否为T的子树

2019独角兽企业重金招聘Python工程师标准>>> #include<iostream> #include <stdlib.h> using namespace std; struct node{int data;node* leftchild;node* rightchild; };bool isSubtree(node* root1,node* root2){if(root2NULL)return true;if(root1N…

ABP Framework 为什么好上手,不好深入?探讨最佳学习姿势!

离写上一篇经验总结 ABP Framework 研习社经验总结&#xff08;6.28-7.2&#xff09;&#xff0c;已经过去两周。ABP Framework 研习社&#xff08;QQ群&#xff1a;726299208&#xff09; 最近两周&#xff0c;又迎来了很多新伙伴&#xff0c;成员数量上升至300。从大家的关注…

见识过世界的强大,才能拥有掌握世界的力量

▲ 点击查看在假期的时候&#xff0c;很多家长会选择带孩子一起出去旅游玩耍。在这个过程当中&#xff0c;家长们可能经常都会被孩子各种稀奇古怪的问题给包围住。“这个车为什么能跑的那么快&#xff1f;“这棵树是什么树&#xff0c;为什么它长得比其他树要高&#xff1f;”…

FastTunnel - 打造人人都能搭建的内网穿透工具

FastTunnel是用.net core开发的一款跨平台内网穿透工具&#xff0c;它可以实现将内网服务暴露到公网供自己或任何人访问。与其他穿透工具不同的是&#xff1a;FastTunnel项目致力于打造一个易于扩展、易于维护的内网穿透框架&#xff0c;任何人都可以基于该框架二次开发&#x…

一招搞定高等数学! | 今日最佳

世界只有3.14 % 的人关注了青少年数学之旅瓜皮儿十三妹没品图一张图让你们看看鲨鱼的血液循环系统到底有多复杂普外科曾医生小猪佩奇其实是“巨猪佩奇”小猪佩奇真实身高为7.1英尺也就是2.16米但她在家还不是最高的一只浪鸭水陆两栖的自行车它出现在1932年的巴黎街头因为加装了…

WPF 表格控件 ReoGrid 的简单使用

WPF 表格控件 ReoGrid 的简单使用目录一、概述二、安装三、添加控件四、加载 Excel五、属性设置六、支持触摸滚动七、其它操作1、显示和隐藏列2、显示特定字体八、资源链接独立观察员 2021 年 7 月 9 日一、概述ReoGrid 是一个开源的表格控件库&#xff0c;支持 Winform 和 WPF…

史上最牛空姐,从飞机上掉下愣是没摔死

全世界只有3.14 % 的人关注了青少年数学之旅珠穆朗玛峰最新的测量高度为8844米&#xff0c;人是血肉之躯&#xff0c;一旦从这么高的地方掉下来&#xff0c;别说生还了&#xff0c;能有个全尸就不错了。但是&#xff0c;历史上却有这么以为超级幸运的女人&#xff0c;她从比珠穆…

nginx对websocket的支持及uliweb chatroom的测试

2019独角兽企业重金招聘Python工程师标准>>> 在尝试在uliweb中使用gevent开发聊天室时&#xff0c;已经在网上搜到nginx是支持websocket的代理的&#xff0c;不过应该不支持集群模式。不过当时没有试过&#xff0c;今天试了一下&#xff0c;在普通的反向代理是没有问…