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

实现思路与技术:

主要用到技术: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. (模拟 打好基础)nyoj1363-计划日

    1363-计划日 内存限制:256MB 时间限制:3000ms 特判: No通过数:21 提交数:79 难度:1 题目描述: 为什么花那么多时间.精力还是学不好学不通,如何把握各科目的重难点,期中和期 ...

  2. <02>labSQL的配置和使用方法

    任务布置:制作简单地铁站点管理系统<2> 要求一:正确配置系统,建立基本正常的数据通道:要求二:实现地铁站点的登记,拥有查询功能: 正文: 今天介绍labview虚拟仪器软件中  labS ...

  3. seq2seq

    seq2seq: seq2seq就是将输入序列经过encoder-decoder变成目标序列. 如图所示,输入序列是 [A, B, C, <EOS>],输出序列是  [W, X, Y, Z ...

  4. 001 Lua相关链接

    Lua官网:http://www.lua.org/ Lua for windows地址:http://www.lua.org/download.html Lua教程:http://www.runoob ...

  5. 【JS】JavaScript 指定日期增加天数

    指定某个日期(字符串),增加n天后,输出日期字符串,格式:年-月-日: /** * [dateAddDays 从某个日期增加n天后的日期] * @param {[string]} dateStr [日 ...

  6. MapReduce-TextInputFormat 切片机制

    MapReduce 默认使用 TextInputFormat 进行切片,其机制如下 (1)简单地按照文件的内容长度进行切片 (2)切片大小,默认等于Block大小,可单独设置 (3)切片时不考虑数据集 ...

  7. http 400错误【原】

    http 400错误现象: 使用java代码访问某PDF文件地址, 报了http 400错误 ,浏览器却能正常访问 . 所以猜测浏览器对地址做了额外处理. 异常代码 String srcUrl = & ...

  8. [C++]UVaLive7324 ASCII Addtion

    Description Nowadays, there are smartphone applications that instantly translate text and even solve ...

  9. 好的java资源地址

    前人栽树,后人乘凉.想当初自己初学Java时为了解决一个很基础的问题,好多的朋友热心的回复我,帮我分析错误.现在为了方便那些Java新手,特给出自己感觉比较好的学习网站和论坛,希望对朋友们能有点帮助. ...

  10. Apache Spark 章节1

    作者:jiangzz 电话:15652034180 微信:jiangzz_wx 微信公众账号:jiangzz_wy 背景介绍 Spark是一个快如闪电的统一分析引擎(计算框架)用于大规模数据集的处理. ...