相信大家都使用过草料二维码生成器,单独生成二维码可以,但是批量生成二维码就需要收费了。既然要收费,那就自己写一个。
接口采用导入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;
}
}