需求场景:客户根据前台界面列表所选择的数据,根据需要的信息批量生成二维码并形成一张图片,并且每张图片显示的二维码数量是固定的,需要分页(即总共生成的二维码图片超出每页显示的需另起一页生成),并下载到客户端。

实现思路与技术:

主要用到技术: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程序-----批量生成二维码并形成一张图片的更多相关文章

  1. C# 动态创建SQL数据库(二) 在.net core web项目中生成二维码 后台Post/Get 请求接口 方式 WebForm 页面ajax 请求后台页面 方法 实现输入框小数多 自动进位展示,编辑时实际值不变 快速掌握Gif动态图实现代码 C#处理和对接HTTP接口请求

    C# 动态创建SQL数据库(二) 使用Entity Framework  创建数据库与表 前面文章有说到使用SQL语句动态创建数据库与数据表,这次直接使用Entriy Framwork 的ORM对象关 ...

  2. 微信小程序之生成二维码

    最近项目中涉及到小程序的生成二维码,很是头疼,经过多次摸索,整理出了自己的一些思想方法,如有不足,欢迎指正. 首先完全按照小程序的结构依次填坑. pages--index.wxml <view ...

  3. 小程序canvas生成二维码图片踩的坑

    1:生成临时图片,保证画布被加载以及渲染(即本身不可以 hidden 或是 上级元素不可以 hidden 或是 wx:if 隐藏等) == > 建议:因为 canvas 的组件层级(z-inde ...

  4. 在.net core web项目中生成二维码

    1.添加QRCoder包引用 2. public IActionResult MakeQrCode()        { string url="https://www.baidu.com& ...

  5. 小程序动态生成二维码,生成image图片

    前端: <image src="{{img_usrl}}" style="width:100%;height:104px;" bindlongtap=&q ...

  6. C# 利用QRCode生成二维码图片

    网上生成二维码的组件是真多,可是真正好用的,并且生成速度很快的没几个,QRCode就是我在众多中找到的,它的生成速度快.但是网上关于它的使用说明,真的太少了,大都是千篇一律的复制粘贴.这是本要用它做了 ...

  7. jquery.qrcode和jqprint的联合使用,实现html生成二维码并打印(中文也ok)

    在公司的生产现场中,常常会在一些部品或设备上贴上二维码,用于扫描录入数据,免去手动输入的麻烦. 以前曾经做过winform的程序,生成二维码,并打印出来,使用的是zxing的类库, 但是如果二维码是附 ...

  8. 在Excel中,不利用任何第三方工具,生成二维码

    有同事提需求,要批量生成二维码.谈了之后,我觉得可以做个excel文件,把要打印的内容放进去,然后给每行数据生成一个二维码.下一步就要在Excel里面生成二维码.问了一下度娘,貌似都得利用一些第三方工 ...

  9. 转【微信小程序 四】二维码生成/扫描二维码

    原文:https://blog.csdn.net/xbw12138/article/details/75213274 前端 二维码生成 二维码要求:每分钟刷新一次,模拟了个鸡肋,添加了个按分钟显示的时 ...

随机推荐

  1. 谈谈JavaScript中继承方式

    聊一聊js中的继承 一.简单继承---使用原型赋值的方式继承,将实例化的对象,赋值给子级的原型 父级构造函数 function Parent(param) { this.name = 'parent' ...

  2. (BST 递归) leetcode98. Validate Binary Search Tree

    Given a binary tree, determine if it is a valid binary search tree (BST). Assume a BST is defined as ...

  3. 课下作业MyCP的分析

    目录 MyCP 题目 截图 代码 相关知识 出现的问题 代码托管 参考资料 MyCP 题目 编写MyCP.java 实现类似Linux下cp XXX1 XXX2的功能,要求MyCP支持两个参数: ja ...

  4. 第九周博客作业<西北师范大学|李晓婷>

    1.助教博客链接:https://home.cnblogs.com/u/lxt-/ 2.作业要求博客链接:https://www.cnblogs.com/nwnu-daizh/p/10726884.h ...

  5. Java基础--面向对象编程3(继承)

    1.继承的作用 为了提取两个类中公共的代码,可以使用继承抽取重复性的代码到一个公共类中. 这个公共的类称为父类(super class),继承于父类的类称为子类(sub class). 2.java继 ...

  6. Springboot集成Spring Batch

    Spring官网 (https://spring.io/projects/spring-batch#overview)对Spring  Batch的解释: 一个轻量级的.全面的批处理框架,用于开发对企 ...

  7. 为什么HashMap线程不安全,Hashtable和ConcurrentHashMap线程安全

    HashMap源码 public V put(K key, V value) { return putVal(hash(key), key, value, false, true); } final ...

  8. 【medium】4. Median of Two Sorted Arrays 两个有序数组中第k小的数

    There are two sorted arrays nums1 and nums2 of size m and n respectively. Find the median of the two ...

  9. python学习第37天

    MySQL数据库 数据库的优势 什么是数据(Data) 什么是数据库(DataBase,简称DB) 什么是数据库管理系统(DataBase Managerment System 简称DBMS) 数据库 ...

  10. R语言︱LDA主题模型——最优主题...

    R语言︱LDA主题模型——最优主题...:https://blog.csdn.net/sinat_26917383/article/details/51547298#comments