Web程序-----批量生成二维码并形成一张图片
需求场景:客户根据前台界面列表所选择的数据,根据需要的信息批量生成二维码并形成一张图片,并且每张图片显示的二维码数量是固定的,需要分页(即总共生成的二维码图片超出每页显示的需另起一页生成),并下载到客户端。
实现思路与技术:
主要用到技术:Qrcode.net(生成二维码的库)
SharpZipLib(压缩库)
.NET GDI绘图
总体思路:根据相关的信息用Qrcode.net 与GDI绘图先绘制成单张二维码图片(如图1),然后再把多个单张生成的二维码按照每页需显示的个数再绘制到一张图上,可生成多张(如:图二),然后服务器再把类似多张(图二)的图片打包到一起,形成一个压缩文件(图三),下载到客户端。


(图1) (图二) (图三)
服务器端主要代码:
//生成二维码
public JsonResult MakeQrcodeImage([Json]List<EquipmentLedger_SheBei> list)
{
string virtual_Path="~/upload/EquipmentImage_Temp/"+Guid.NewGuid().ToString();
string folderName = Server.MapPath(virtual_Path);
Directory.CreateDirectory(folderName);
foreach (var li in list)
{
DrawQrCode(li, folderName);
}
int pageIndex = ;
int pageSize = ;
decimal totalCount =Convert.ToDecimal(list.Count);
decimal pages =Math.Ceiling(totalCount / pageSize);
List<string> fildes = new List<string>();
for (int i = ; i <= pages; i++)
{ var list_new = (from s in list
orderby s.Id descending
select s).Skip((pageIndex - ) * pageSize).Take(pageSize).ToList<EquipmentLedger_SheBei>(); CombineImage(list_new, pageIndex, folderName);
pageIndex++; } for (int j = ; j <= pages; j++){ fildes.Add(folderName + "/QrCodes-Page" + j + ".bmp"); }
string saveFile = folderName + "/QrCodesTest.zip";
Zip(fildes.ToArray(),saveFile);
return Json(new MyJsonResult() { success = true, data = virtual_Path + "/QrCodesTest" }, null, null); }
public FilePathResult DownLoadImage(string fieldName)
{ return File(Server.MapPath(fieldName) + ".zip", "application/octet-stream", "EquipmentLedgerQrCodes.zip"); }
//删除临时文件夹
public JsonResult DleteTempMakeQrcodeImage(string fieldName)
{ Directory.Delete(Server.MapPath(fieldName.Replace("/QrCodesTest","")),true);
return Json(new MyJsonResult() { success = true }, null, null); }
//绘制二维码
private void DrawQrCode(EquipmentLedger_SheBei eq,string folderName){
byte[] bytes = Encoding.Default.GetBytes(eq.Id.ToString());
string content = Convert.ToBase64String(bytes); ;
int moduleSize = ;
var encoder = new QrEncoder(ErrorCorrectionLevel.M);
QrCode qrCode = encoder.Encode(content);
GraphicsRenderer render = new GraphicsRenderer(new FixedModuleSize(moduleSize, QuietZoneModules.Four), Brushes.Black, Brushes.White);
DrawingSize dSize = render.SizeCalculator.GetSize(qrCode.Matrix.Width); RectangleF Rec_Top = new Rectangle(new Point(, ), new Size(dSize.CodeWidth, ));//顶部文字框
RectangleF Rec_botom_Num = new Rectangle(new Point(, dSize.CodeWidth - ), new Size(dSize.CodeWidth, ));//底部文字框
//创建画布
using (Bitmap map = new Bitmap(dSize.CodeWidth, dSize.CodeWidth))
{
Graphics g = Graphics.FromImage(map); g.Clear(Color.White);
Font drawFont = new Font("宋体", , FontStyle.Bold);
SolidBrush drawBrush = new SolidBrush(Color.Red);
render.Draw(g, qrCode.Matrix, new Point(, ));
StringFormat sf = new StringFormat();
sf.Alignment = StringAlignment.Center;
sf.LineAlignment = StringAlignment.Center;
g.DrawString(eq.Name, drawFont, drawBrush, Rec_Top, sf);
g.DrawString(eq.Number, drawFont, drawBrush, Rec_botom_Num, sf);
map.Save(folderName + "/" + eq.Id + ".bmp", ImageFormat.Bmp);//fileName为存放的图片路径
g.Dispose();
map.Dispose();//释放bmp文件资源 } }
private void Zip(string[] files, string ZipedFileName)
{
Zip(files, ZipedFileName, string.Empty);
}
private void Zip(string[] files, string ZipedFileName, string Password)
{
files = files.Where(f => System.IO.File.Exists(f)).ToArray();
if (files.Length != )
{
ZipOutputStream s = new ZipOutputStream(System.IO.File.Create(ZipedFileName));
s.SetLevel();
if (!string.IsNullOrEmpty(Password.Trim())) s.Password = Password.Trim();
ZipFileDictory(files, s);
s.Finish();
s.Close();
}
} /// <summary>
/// 压缩多个文件
/// </summary>
/// <param name="files">文件名</param>
/// <param name="ZipedFileName">压缩包文件名</param>
/// <returns></returns>
private void ZipFileDictory(string[] files, ZipOutputStream s)
{
ZipEntry entry = null;
FileStream fs = null;
Crc32 crc = new Crc32();
try
{
//创建当前文件夹
entry = new ZipEntry("/");
s.PutNextEntry(entry);
s.Flush();
foreach (string file in files)
{
//打开压缩文件
fs = System.IO.File.OpenRead(file); byte[] buffer = new byte[fs.Length];
fs.Read(buffer, , buffer.Length);
entry = new ZipEntry("/" + Path.GetFileName(file));
entry.DateTime = DateTime.Now;
entry.Size = fs.Length;
fs.Close();
crc.Reset();
crc.Update(buffer);
entry.Crc = crc.Value;
s.PutNextEntry(entry);
s.Write(buffer, , buffer.Length);
}
}
finally
{
if (fs != null)
{
fs.Close();
fs = null;
}
if (entry != null)
entry = null;
GC.Collect();
}
}
//生成每页多张二维码的图片
private void CombineImage(List<EquipmentLedger_SheBei> list,int pageNum,string folderName)
{ int rows = ;
int cols = ;
int height = ;
int width = ;
int currentIndex = ; using (Bitmap bt1 = new Bitmap(, ))
{
List<Rectangle> recs = new List<Rectangle>();
Graphics g = Graphics.FromImage(bt1);
g.Clear(Color.White); for (int col = ; col < cols; col++)
{
for (int row = ; row < rows; row++)
{
if (list.Count >= currentIndex)
{ using (Bitmap bm = new Bitmap(folderName + "/" + list[currentIndex - ].Id + ".bmp"))
{
Rectangle rg = new Rectangle(col * height, row * width + row * +, width, height);
g.DrawImage(bm, rg);
currentIndex++;
}
}
}
}
//要绘制到的位图
bt1.Save(folderName + "/QrCodes-Page" + pageNum + ".bmp", ImageFormat.Bmp);//fileName为存放的图片路径
g.Dispose();
bt1.Dispose();//释放bmp文件资源
}
}
前端Extjs代码:
makeQrcodeImage: function () {
var me = this;
var record = me.getList().getSelectionModel().getSelection()[0];
if (record == null) {
Ext.Msg.alert("系统提示", "请选择要生成二维码图片的设备");
return;
} else {
var maiView = Ext.ComponentQuery.query('MainView')[0];
me.PicMask = new Ext.LoadMask(maiView, { msg: "图片生成中,请稍后..." });
me.PicMask.show();
var records = me.getList().getSelectionModel().getSelection();
var list = [];
for (var i = 0; i < records.length; i++) {
list.push(records[i].data);
}
Ext.Ajax.request({
url: "../../EquipmentLedgerSheBei/MakeQrcodeImage",
async: true,
scope: this,
params: {
list: Ext.util.base64.encode(Ext.JSON.encode(list)),
},
success: function (Response) {
var flag = Ext.JSON.decode(Response.responseText).success;
if (flag) {
//下载文件
window.open("../../EquipmentLedgerSheBei/DownLoadImage?fieldName=" + Ext.JSON.decode(Response.responseText).data, "_blank");
me.PicMask.hide();
Ext.Ajax.request({
url: "../../EquipmentLedgerSheBei/DleteTempMakeQrcodeImage",
async: true,
scope: this,
params: {
fieldName: Ext.JSON.decode(Response.responseText).data,
}
});
}
}
})
}
}
Web程序-----批量生成二维码并形成一张图片的更多相关文章
- C# 动态创建SQL数据库(二) 在.net core web项目中生成二维码 后台Post/Get 请求接口 方式 WebForm 页面ajax 请求后台页面 方法 实现输入框小数多 自动进位展示,编辑时实际值不变 快速掌握Gif动态图实现代码 C#处理和对接HTTP接口请求
C# 动态创建SQL数据库(二) 使用Entity Framework 创建数据库与表 前面文章有说到使用SQL语句动态创建数据库与数据表,这次直接使用Entriy Framwork 的ORM对象关 ...
- 微信小程序之生成二维码
最近项目中涉及到小程序的生成二维码,很是头疼,经过多次摸索,整理出了自己的一些思想方法,如有不足,欢迎指正. 首先完全按照小程序的结构依次填坑. pages--index.wxml <view ...
- 小程序canvas生成二维码图片踩的坑
1:生成临时图片,保证画布被加载以及渲染(即本身不可以 hidden 或是 上级元素不可以 hidden 或是 wx:if 隐藏等) == > 建议:因为 canvas 的组件层级(z-inde ...
- 在.net core web项目中生成二维码
1.添加QRCoder包引用 2. public IActionResult MakeQrCode() { string url="https://www.baidu.com& ...
- 小程序动态生成二维码,生成image图片
前端: <image src="{{img_usrl}}" style="width:100%;height:104px;" bindlongtap=&q ...
- C# 利用QRCode生成二维码图片
网上生成二维码的组件是真多,可是真正好用的,并且生成速度很快的没几个,QRCode就是我在众多中找到的,它的生成速度快.但是网上关于它的使用说明,真的太少了,大都是千篇一律的复制粘贴.这是本要用它做了 ...
- jquery.qrcode和jqprint的联合使用,实现html生成二维码并打印(中文也ok)
在公司的生产现场中,常常会在一些部品或设备上贴上二维码,用于扫描录入数据,免去手动输入的麻烦. 以前曾经做过winform的程序,生成二维码,并打印出来,使用的是zxing的类库, 但是如果二维码是附 ...
- 在Excel中,不利用任何第三方工具,生成二维码
有同事提需求,要批量生成二维码.谈了之后,我觉得可以做个excel文件,把要打印的内容放进去,然后给每行数据生成一个二维码.下一步就要在Excel里面生成二维码.问了一下度娘,貌似都得利用一些第三方工 ...
- 转【微信小程序 四】二维码生成/扫描二维码
原文:https://blog.csdn.net/xbw12138/article/details/75213274 前端 二维码生成 二维码要求:每分钟刷新一次,模拟了个鸡肋,添加了个按分钟显示的时 ...
随机推荐
- linux 单用户密码修改
1.启动系统,并在GRUB2启动屏显时,按下e键进入编辑模式. 2.在linux16/inux/linuxef所在参数行ro更改为init=/sysroot/bin/sh 3.按Crl+x启动到she ...
- rocketmq 启动和停止命令
A启动server: nohup sh mqnamesrv &A启动broken: nohup sh mqbroker -c /opt/rocketmq432/conf/2m-noslave/ ...
- ant 执行jmeter
构建-invoke ant -properties jmeter.home=/home/userapp/apps/apache-jmeter-5.0report.title=kyh_register_ ...
- Android studio Error: Modules no specified解决和真机调试
如何配置SDK百度一大堆: 前言:Android Studio很完善,如果SDK配置好,理论上就是 创建项目->创建个APP(名字自己随便起)->打开手机开发者模式运行即可:如果出了问题, ...
- 在思科路由器上配置AAA实验(Cisco PT)
1.拓扑图 Addressing Table 地址表 Device Interface IP Address Subnet Mask R1 Fa0/0 192.168.1.1 ...
- 01.QT初学--两个窗口相互切换
//qqwidget.cpp #include "qqwidget.h" #include "ui_qqwidget.h" qqwidget::qqwidget ...
- CentOS 6.6 系统升级到 CentOS 6.7
1.利用Centos6.7 ISO镜像挂载为本地镜像 创建一个挂载目录 CentOS 6.6 系统升级到 CentOS 6.7 mkdir /mnt/data 2.挂载镜像(远程镜像) mount - ...
- python-类内置属性和内置方法
class A(): ''' 这是一个类 ''' banji=1 def __init__(self,name,age): self.name=name self.age=age def AA(sel ...
- kai linux安装搜狗输入法以及更新源地址
需要去搜狗官网下载linux版的输入法,根据自己的系统选择多少位进行下载. 首先执行如下命令:dpkg -i 输入法包名,这时会报错,会报没有安装依赖包,这时需要执行apt-get install - ...
- 不同IDE对maven项目静态资源处理
今天自己构建maven管理的web项目,参照另一位兄弟的代码,发现他的静态资源,也就是html.js之类的文件是在src/main/resource目录下的,我的在src/main/resource目 ...