C#实现批量生成二维码

相信大家都使用过草料二维码生成器,单独生成二维码可以,但是批量生成二维码就需要收费了。既然要收费,那就自己写一个。

接口采用导入Excel文件生成二维码,首先需要读取Excel的数据,方法如下所示:

csharp 复制代码
/// <summary>
/// 读取数据
/// </summary>
/// <returns>Workbook</returns>
public static DataTable GetExcel(string Path, ref string exceptionMsg)
{
    //定义datatable
    DataTable dtExcel = new DataTable();
    //思路:
    //1、获取读取的文件;2、把文件转换为二进制数组;3、二进制数组转成内存流;4、利用NPOI把内存流中的数据读取成Excel
    FileStream fs = new FileStream(Path, FileMode.Open, FileAccess.Read);
    //声明二进制数组存放文件
    byte[] fileBytes = new byte[fs.Length];
    //将传入的文件转化为二进制的数组存入fileBytes
    fs.Read(fileBytes, 0, (int)fs.Length);
    //将二进制的数组转化为内存流
    MemoryStream excelFileStream = new MemoryStream(fileBytes);
    //将内存流转化为工作簿
    NPOI.SS.UserModel.IWorkbook workbook = new NPOI.HSSF.UserModel.HSSFWorkbook(excelFileStream);

    //判断工作簿中是否有工作表
    if (!(workbook.NumberOfSheets > 0))
    {
        exceptionMsg = "工作簿中没有数据表";
        return dtExcel;
    }
    //获取第一个工作表
    NPOI.SS.UserModel.ISheet sheet = workbook.GetSheetAt(0);
    //PhysicalNumberOfRows 获取的是物理行数,也就是不包括那些空行(隔行)的情况。
    //判断工作表中是否有数据
    if (!(sheet.PhysicalNumberOfRows > 0))
    {
        exceptionMsg = "数据表为空";
        return dtExcel;
    }

    //将数据装到DataTable中
    //获取标题行
    NPOI.SS.UserModel.IRow rowHeader = sheet.GetRow(0);

    /*
        FirstCellNum:获取某行第一个单元格下标
        LastCellNum:获取某行的列数
        FirstRowNum:获取第一个实际行的下标
        LastRowNum:获取最后一个实际行的下标
    */
    //获取表格列数
    int cellCount = rowHeader.LastCellNum;
    //获取表格行数(最后一行下标+1)
    int rowCount = sheet.LastRowNum + 1;

    //创建dataTable中的列,循环添加标题行中各个单元格的数据
    for (int i = rowHeader.FirstCellNum; i < cellCount; i++)
    {
        //遍历表头行中每一个单元格,获取标题行各个单元格的数据
        DataColumn dtColumn = new DataColumn(rowHeader.GetCell(i).StringCellValue);
        //将获取到的标题行的数据放到dataTable中
        dtExcel.Columns.Add(dtColumn);
    }

    int hang = sheet.FirstRowNum;
    try
    {
        //读取Excel中的数据
        //(sheet.FirstRowNum) 第一行是标题
        for (int i = sheet.FirstRowNum + 1; i < rowCount; i++)
        {
            hang = i;
            //获取'i'行数据
            NPOI.SS.UserModel.IRow row = sheet.GetRow(i);
            //创建DataTable行
            DataRow dtRow = dtExcel.NewRow();
            if (row != null)
            {
                //遍历excel中一行所有的单元格
                for (int j = row.FirstCellNum; j < cellCount; j++)
                {
                    if (row.GetCell(j) != null)
                    {
                        switch (row.GetCell(j).CellType)
                        {
                            case CellType.Formula://此处是处理公式数据,获取公式执行后的值
                                HSSFFormulaEvaluator eva = new HSSFFormulaEvaluator(workbook);
                                if (eva.Evaluate(row.GetCell(j)).CellType == CellType.Numeric)
                                    dtRow[j] = eva.Evaluate(row.GetCell(j)).NumberValue;
                                else
                                    dtRow[j] = eva.Evaluate(row.GetCell(j)).StringValue;
                                break;
                            default:
                                dtRow[j] = row.GetCell(j).ToString();
                                break;
                        }
                    }
                }
            }
            //新行添加到dataTable中
            dtExcel.Rows.Add(dtRow);
        }
    }
    catch (Exception)
    {
        exceptionMsg = "第" + hang + "行数据存在异常";
        return dtExcel;
    }
    return dtExcel;
}

读取到数据后,生成二维码。

csharp 复制代码
public string FileUploadQRCode(){
	DataTable dt = ExcelFile.GetExcel(Path, ref msg);//Excel文件路径Path
	if (msg != "")
	{
	    //返回失败信息
	    return "{code: 0, msg: \"" + msg + "\"}");
	}
	for (int i = 0; i < dt.Rows.Count; i++)
	{
	    if (string.IsNullOrEmpty(dt.Rows[i]["名称"].ToString()) && string.IsNullOrEmpty(dt.Rows[i]["内容"].ToString()))//名称、内容代表表格列名
	        continue;
	    var text= dt.Rows[i]["名称"].ToString();
	    var data = dt.Rows[i]["内容"].ToString();
	    var str = "https://xx.shuangruixin.cn/api/xcx/tool.aspx?opt=MakeTextQRCode&data=" + data + "&text=" + text;//生成二维码服务地址
	    SaveImageFromWeb(str, "C:\\Users\\Administrator\\Desktop\\二维码\\", text);
	}
}

其中生成二维码服务代码如下:

csharp 复制代码
public void MakeTextQRCode()
{
    if (!string.IsNullOrEmpty(Request.QueryString["data"]) && !string.IsNullOrEmpty(Request.QueryString["text"]))
    {
        string str = Request.QueryString["data"];
        BarcodeWriter writer = new BarcodeWriter();
        writer.Format = BarcodeFormat.QR_CODE;
        QrCodeEncodingOptions options = new QrCodeEncodingOptions()
        {
            DisableECI = true,//设置内容编码
            CharacterSet = "UTF-8",
            Width = 500,//设置二维码的宽度和高度
            Height = 600,
            Margin = 1//设置二维码的边距,单位不是固定像素
        };

        writer.Options = options;
        Bitmap image = writer.Write(str);

        #region 添加文本
        Bitmap backgroudImg = new Bitmap(image.Width, image.Height);
        backgroudImg.MakeTransparent();
        Graphics g2 = Graphics.FromImage(backgroudImg);
        g2.Clear(Color.Transparent);
        //画二维码到新的面板上
        g2.DrawImage(image, 0, 0);
        string content = Request.QueryString["text"];
        if (!string.IsNullOrEmpty(content))
        {
            FontFamily fontFamily = new FontFamily("楷体");
            System.Drawing.Font font1 = new System.Drawing.Font(fontFamily, 30f, FontStyle.Bold, GraphicsUnit.Pixel);

            //文字长度 
            int strWidth = (int)g2.MeasureString(content, font1).Width;
            //总长度减去文字长度的一半(居中显示)
            int wordStartX = (image.Width - strWidth) / 2;
            int wordStartY = image.Height - 55;

            g2.DrawString(content, font1, Brushes.Black, wordStartX, wordStartY);
        }
        g2.Dispose();
        #endregion

        //保存为PNG到内存流
        MemoryStream ms = new MemoryStream();
        backgroudImg.Save(ms, ImageFormat.Png);

        Response.ContentType = "image/png";
        //输出二维码图片
        Response.BinaryWrite(ms.GetBuffer());
        Response.End();
    }
}

最后将生成的二维码保存到指定的路径。

csharp 复制代码
 public static int SaveImageFromWeb(string imgUrl, string path, string fileName)
 {
     if (path.Equals(""))
         throw new Exception("未指定保存文件的路径");

     string imgName = imgUrl.ToString().Substring(imgUrl.ToString().LastIndexOf("/") + 1);
     string defaultType = ".png";
     string[] imgTypes = new string[] { ".jpg", ".jpeg", ".png", ".gif", ".bmp" };
     string imgType = imgUrl.ToString().Substring(imgUrl.ToString().LastIndexOf("."));
     foreach (string it in imgTypes)
     {
         if (imgType.ToLower().Equals(it))
             break;
         if (it.Equals(".bmp"))
             imgType = defaultType;
     }

     HttpWebRequest request = (HttpWebRequest)WebRequest.Create(imgUrl);
     request.UserAgent = "Mozilla/6.0 (MSIE 6.0; Windows NT 5.1; Natas.Robot)";
     request.Timeout = 3000;

     WebResponse response = request.GetResponse();
     Stream stream = response.GetResponseStream();

     if (response.ContentType.ToLower().StartsWith("image/"))
     {
         byte[] arrayByte = new byte[1024];
         int imgLong = (int)response.ContentLength;
         int l = 0;
         if (fileName == "")
             fileName = imgName;
         if (!Directory.Exists(path))
         {
             //创建文件夹
             Directory.CreateDirectory(path);
         }
         string URL = path + fileName + imgType;
         FileStream fso = new FileStream(URL, FileMode.Create);
         while (l < imgLong)
         {
             int i = stream.Read(arrayByte, 0, 1024);
             fso.Write(arrayByte, 0, i);
             l += i;
         }

         fso.Close();
         stream.Close();
         response.Close();

         return 1;
     }
     else
     {
         return 0;
     }
 }
相关推荐
重生之我在20年代敲代码29 分钟前
strncpy函数的使用和模拟实现
c语言·开发语言·c++·经验分享·笔记
爱上语文30 分钟前
Springboot的三层架构
java·开发语言·spring boot·后端·spring
编程零零七3 小时前
Python数据分析工具(三):pymssql的用法
开发语言·前端·数据库·python·oracle·数据分析·pymssql
2401_858286114 小时前
52.【C语言】 字符函数和字符串函数(strcat函数)
c语言·开发语言
铁松溜达py4 小时前
编译器/工具链环境:GCC vs LLVM/Clang,MSVCRT vs UCRT
开发语言·网络
everyStudy4 小时前
JavaScript如何判断输入的是空格
开发语言·javascript·ecmascript
C-SDN花园GGbond5 小时前
【探索数据结构与算法】插入排序:原理、实现与分析(图文详解)
c语言·开发语言·数据结构·排序算法
迷迭所归处6 小时前
C++ —— 关于vector
开发语言·c++·算法
架构文摘JGWZ7 小时前
Java 23 的12 个新特性!!
java·开发语言·学习
leon6257 小时前
优化算法(一)—遗传算法(Genetic Algorithm)附MATLAB程序
开发语言·算法·matlab