zoukankan      html  css  js  c++  java
  • (C#)根据文字信息,生成电子凭证(图片)

    实现目的:

            财务中有收保证金与加盟费的操作,纸质的发票保存起来容易丢失,并且不容易查找,于是要改用电子收据的方式来实现:电子收据的样式,是根据实际的纸质收据截图进来的,如下图。我们要实现的是,一旦收据数据从前台传入到后台,后台就根据数据合成一张收据图片并上传服务器:

       

    实现代码:

    A.电子收据中实体定义:

    public class ElectronicReceipt : IDbTracking

    {

    [Key]

    /// <summary>
    ///
    /// </summary>
    public int PKID { get; set; }

    /// <summary>
    /// 账单ID
    /// </summary>
    public int StateId { get; set; }
    public int ShopId { get; set; }

    private string shopName = string.Empty;
    /// <summary>
    /// 收据编号
    /// </summary>
    public string ShopName
    {
    get { return this.shopName ?? string.Empty; }
    set { this.shopName = value; }
    }

    private string receiptNo = string.Empty;
    /// <summary>
    /// 收据编号
    /// </summary>
    public string ReceiptNo
    {
    get { return this.receiptNo ?? string.Empty; }
    set { this.receiptNo = value; }
    }

    private string bizType = string.Empty;
    /// <summary>
    /// 业务单据类型
    /// </summary>
    public string BizType
    {
    get { return this.bizType ?? string.Empty; }
    set { this.bizType = value; }
    }

    /// <summary>
    /// 入账日期
    /// </summary>
    public System.DateTime ReceivedDate { get; set; }

    private string paidBusiness = string.Empty;
    /// <summary>
    /// 交款单位
    /// </summary>
    public string PaidBusiness
    {
    get { return this.paidBusiness ?? string.Empty; }
    set { this.paidBusiness = value; }
    }

    private string receiveMethod = string.Empty;
    /// <summary>
    /// 收款方式
    /// </summary>
    public string ReceiveMethod
    {
    get { return this.receiveMethod ?? string.Empty; }
    set { this.receiveMethod = value; }
    }

    /// <summary>
    /// 人民币
    /// </summary>
    public decimal ReceiveAmount { get; set; }

    private string receiveRemark = string.Empty;
    /// <summary>
    /// 收款事由
    /// </summary>
    public string ReceiveRemark
    {
    get { return this.receiveRemark ?? string.Empty; }
    set { this.receiveRemark = value; }
    }

    private string createdBy = string.Empty;
    /// <summary>
    /// 创建人
    /// </summary>
    public string CreatedBy
    {
    get { return this.createdBy ?? string.Empty; }
    set { this.createdBy = value; }
    }

    private string urlImg = string.Empty;
    /// <summary>
    /// 创建人
    /// </summary>
    public string UrlImg
    {
    get { return this.urlImg ?? string.Empty; }
    set { this.urlImg = value; }
    }

    /// <summary>
    /// 创建人
    /// </summary>
    public System.DateTime CreateTime { get; set; }

    /// <summary>
    /// 最后更新时间
    /// </summary>
    public System.DateTime LastUpdateTime { get; set; }

    private string receiveAmountChinese = string.Empty;
    /// <summary>
    ///
    /// </summary>
    public string ReceiveAmountChinese
    {
    get { return this.receiveAmountChinese ?? string.Empty; }
    set { this.receiveAmountChinese = value; }
    }

    private string optionStatus = string.Empty;
    /// <summary>
    ///
    /// </summary>
    public string OptionStatus
    {
    get { return this.optionStatus ?? string.Empty; }
    set { this.optionStatus = value; }
    }
    /// <summary>
    /// 是否删除
    /// </summary>
    public bool IsDeleted { get; set;}

    /// <summary>
    ///费用属性(Normal:基础,Upgrade:升级)
    /// </summary>
    public string CostAttribute { get; set; }


    public override string ToString()
    {
    return new StringBuilder()
    .AppendLine($"账单ID:{this.StateId}")
    .AppendLine($"收据编号:{this.ReceiptNo}")
    .AppendLine($"业务单据类型:{this.BizType}")
    .AppendLine($"入账日期:{this.ReceivedDate}")
    .AppendLine($"交款单位:{this.PaidBusiness}")
    .AppendLine($"收款方式:{this.ReceiveMethod}")
    .AppendLine($"人民币:{this.ReceiveAmount}")
    .AppendLine($"收款事由:{this.ReceiveRemark}")
    .AppendLine($"创建人:{this.CreatedBy}")
    .AppendLine($"费用属性:{this.CostAttribute}")
    .AppendLine($"创建时间:{this.CreateTime}")
    .AppendLine($"最后更新时间:{this.LastUpdateTime}")
    .ToString();
    }
    }

    B.定义封装绘制图片的类 

    //把文字合成到切图中去,相当于是加水印的方式

    public class DrawImg
    {
    public static byte[] DrawWords(WaterImage image)
    {
    // 源图片全路径
    string sourcePictureName = image.PicturePath + image.SourcePicture;
    string fileExtension = System.IO.Path.GetExtension(sourcePictureName).ToLower();
    // 判断文件是否存在,以及文件名是否正确
    if (System.IO.File.Exists(sourcePictureName) == false || (
    fileExtension != ".gif" &&
    fileExtension != ".jpg" &&
    fileExtension != ".png"))
    {
    return null;
    }

    // 目标图片名称及全路径
    string targetImage = sourcePictureName.Replace(System.IO.Path.GetExtension(sourcePictureName), "") + "_" + DateTime.Now.ToString("yyyyMMddhhmmssfff") + ".jpg";
    //创建一个图片对象用来装载要被添加水印的图片
    Image imgPhoto = Image.FromFile(sourcePictureName);
    //获取图片的宽和高
    int phWidth = imgPhoto.Width;
    int phHeight = imgPhoto.Height;

    //建立一个bitmap,和我们需要加水印的图片一样大小
    Bitmap bmPhoto = new Bitmap(phWidth, phHeight, PixelFormat.Format24bppRgb);
    //SetResolution:设置此 Bitmap 的分辨率
    //这里直接将我们需要添加水印的图片的分辨率赋给了bitmap
    bmPhoto.SetResolution(imgPhoto.HorizontalResolution, imgPhoto.VerticalResolution);
    //Graphics:封装一个 GDI+ 绘图图面。
    Graphics grPhoto = Graphics.FromImage(bmPhoto);

    //设置图形的品质
    grPhoto.SmoothingMode = SmoothingMode.AntiAlias;

    //将我们要添加水印的图片按照原始大小描绘(复制)到图形中
    grPhoto.DrawImage(
    imgPhoto, // 要添加水印的图片
    new Rectangle(0, 0, phWidth, phHeight), // 根据要添加的水印图片的宽和高
    0, // X方向从0点开始描绘
    0, // Y方向
    phWidth, // X方向描绘长度
    phHeight, // Y方向描绘长度
    GraphicsUnit.Pixel); // 描绘的单位,这里用的是像素


    //根据图片的大小我们来确定添加上去的文字的大小
    //在这里我们定义一个数组来确定
    int[] sizes = new int[] { 16, 14, 12, 10, 8, 6, 4 };

    //字体
    Font crFont = null;
    //矩形的宽度和高度,SizeF有三个属性,分别为Height高,width宽,IsEmpty是否为空
    SizeF crSize = new SizeF();
    int yPixlesFromBottom = (int)(phHeight * .05);


    foreach (var wordInfo in image.words)
    {
    //利用一个循环语句来选择我们要添加文字的型号
    //直到它的长度比图片的宽度小
    for (int i = 0; i < 7; i++)
    {
    crFont = new Font("arial", sizes[i], FontStyle.Bold);

    //测量用指定的 Font 对象绘制并用指定的 StringFormat 对象格式化的指定字符串。
    crSize = grPhoto.MeasureString(wordInfo.Words, crFont);

    // ushort 关键字表示一种整数数据类型
    if ((ushort)crSize.Width < (ushort)phWidth)
    break;
    }

    //封装文本布局信息(如对齐、文字方向和 Tab 停靠位),显示操作(如省略号插入和国家标准 (National) 数字替换)和 OpenType 功能。
    StringFormat StrFormat = new StringFormat();

    //定义需要印的文字居中对齐
    StrFormat.Alignment = StringAlignment.Near;
    SolidBrush semiTransBrush = new SolidBrush(wordInfo.color);
    //绘制图形
    grPhoto.DrawString(wordInfo.Words, //string of text
    crFont, //font
    semiTransBrush, //Brush
    new PointF(wordInfo.Position.xPosOfPic, wordInfo.Position.yPosOfPic), //Position
    StrFormat);
    }
    //imgPhoto是我们建立的用来装载最终图形的Image对象
    //bmPhoto是我们用来制作图形的容器,为Bitmap对象
    imgPhoto = bmPhoto;
    //释放资源,将定义的Graphics实例grPhoto释放,grPhoto功德圆满
    grPhoto.Dispose();

    //将grPhoto保存
    //将图片上传服务器,并保存
    //将图片保存在文件服务器上

    var imgPhotoByte = ConvertImage(imgPhoto);
    imgPhoto.Dispose();
    return imgPhotoByte;
    //保存文件
    //imgPhoto.Save(targetImage, ImageFormat.Jpeg);
    }


    /// <summary>
    /// 将Image转换为byte[] 用来存放是数据库中
    /// </summary>
    /// <param name="image">Image</param>
    /// <returns>byte[]</returns>
    public static byte[] ConvertImage(Image image)
    {
    using (var bitMag = new Bitmap(image))
    {
    using (var stream = new MemoryStream())
    {
    bitMag.Save(stream, ImageFormat.Jpeg);
    var bateArr = stream.ToArray();
    return bateArr;
    }
    }
    }
    }

    //准备要合成的图片的原材料信息(图片与要合成的字)

    public class WaterImage
    {
    public WaterImage()
    {
    words = new List<WaterWord>();
    }

    /// <summary>
    /// 文件名称
    /// </summary>
    public string SourcePicture;
    /// <summary>
    /// 文件地址
    /// </summary>
    public string PicturePath;
    /// <summary>
    /// 要打水印的文字
    /// </summary>
    public List<WaterWord> words { get; set; }
    }

    ///要合成的字的样式,位置,大小的配置类

    public class WaterWord
    {
    public WaterWord()
    {
    Alpha = (float)0.9;
    //字体颜色
    color = Color.FromArgb(255, 0, 0, 0);
    }

    /// <summary>
    /// 透明度 0-1
    /// </summary>
    public float Alpha;
    public ImagePosition Position;
    public string Words;
    /// <summary>
    /// 文字的颜色
    /// </summary>
    public Color color { get; set; }
    }

    ///要加入图片的位置信息

    public class ImagePosition
    {
    public ImagePosition()
    {
    xPosOfPic = 0;
    yPosOfPic = 0;
    }

    public float xPosOfPic { get; set; }
    public float yPosOfPic { get; set; }
    }

    //组装操作  绘制图片并上传文件

    public string UploadReceiveVoucherDoc(ElectronicReceipt er)
    {
    if (er == null)
    {
    return string.Empty;
    }

    var waterImag = new WaterImage()
    {
    PicturePath = AppDomain.CurrentDomain.BaseDirectory,
    SourcePicture = @"ReceiveVoucher.jpg",
    };

    EnvironmentHandler.Instance.Logger.Log(Level.Info, waterImag.PicturePath + waterImag.SourcePicture, "图片的模板地址");

    //收据号码
    waterImag.words.Add(new WaterWord()
    {
    Words = er.ReceiptNo,
    Position = new ImagePosition() { xPosOfPic = 1000, yPosOfPic = 70 }
    });
    //入账日期
    waterImag.words.Add(new WaterWord()
    {
    Words = er.ReceivedDate.ToString("yyyy MM dd"),
    Position = new ImagePosition() { xPosOfPic = 660, yPosOfPic = 148 }
    });
    //交款单位
    waterImag.words.Add(new WaterWord()
    {
    Words = er.CreatedBy,
    Position = new ImagePosition() { xPosOfPic = 311, yPosOfPic = 245 }
    });
    //收款方式
    waterImag.words.Add(new WaterWord()
    {
    Words = er.PaidBusiness,
    Position = new ImagePosition() { xPosOfPic = 970, yPosOfPic = 245 }
    });
    //人民币(大写)
    var words = er.ReceiveAmountChinese;
    if (er.ReceiveAmount - (int)er.ReceiveAmount == 0 && !words.EndsWith("整"))
    {
    words += "整";
    }
    waterImag.words.Add(new WaterWord()
    {
    Words = words,
    Position = new ImagePosition() { xPosOfPic = 329, yPosOfPic = 322 }
    });
    //人民币(小写)
    waterImag.words.Add(new WaterWord()
    {
    Words = er.ReceiveAmount.ToString("0.00"),
    Position = new ImagePosition() { xPosOfPic = 928, yPosOfPic = 315 }
    });
    //收款事由
    waterImag.words.Add(new WaterWord()
    {
    Words = "【" + er.ShopId + "】-" + er.ReceiveRemark,
    Position = new ImagePosition() { xPosOfPic = 294, yPosOfPic = 404 }
    });
    //落款年月
    waterImag.words.Add(new WaterWord()
    {
    Words = DateTime.Now.ToString("yyyy MM dd"),
    Position = new ImagePosition() { xPosOfPic = 928, yPosOfPic = 462 }
    });
    var bitys = DrawImg.DrawWords(waterImag);
    EnvironmentHandler.Instance.Logger.Log(Level.Info, bitys.ToString(), "图片二进制");
    if (bitys != null)
    {
    var fileDirectory = @"/finance/ShopBillReceiptVoucher/" + DateTime.Now.ToString("yyyyMMdd");
    var uploadRequest = new ImageUploadRequest(fileDirectory, bitys);

    //上传文件到服务器上,封装的上传方法,根据各自的情况而定
    var filePath = UploadImageAsync(uploadRequest).Result;
    EnvironmentHandler.Instance.Logger.Log(Level.Info, filePath, "UploadReceiveVoucherDoc 图片的地址");
    return filePath;
    }
    return "";
    }

  • 相关阅读:
    hdu--4027--不错的线段树
    hdu--3275--线段树<again>
    hdu--2795--又是线段树
    hdu--4407--一不留神就TLE了
    zoj--3822--第二题概率dp
    hdu--3911--线段树<我最近爱上她了>
    hdu--1710--二叉树的各种遍历间的联系
    hdu--1712--分组背包<如果你真的明白了背包..>
    hdu--4576--概率dp<见过最简单的概率dp>
    list remove object
  • 原文地址:https://www.cnblogs.com/q994321263/p/10973603.html
Copyright © 2011-2022 走看看