65.9K
CodeProject 正在变化。 阅读更多。
Home

每个标签的打印画布模式 - 画布内画布

emptyStarIconemptyStarIconemptyStarIconemptyStarIconemptyStarIcon

0/5 (0投票)

2014年11月19日

CPOL

2分钟阅读

viewsIcon

9245

通过 HTML Canvas 实现地址或条形码标签。

引言

本文介绍如何使用HTML Canvas开发地址或条形码标签。文章分为两部分:

  1. 带有字段的内部画布
  2. 带有对齐的内部画布重复的外部画布

背景

我在我的Web项目中有一个任务,需要开发各种标签尺寸的模式。我发现可以使用HTML Canvas来实现。我也找到了很多Canvas的示例,但没有一个完全满足我的需求,因为我首先需要开发带有字段的内部画布,然后使用该画布以重复模式形成外部画布。经过四处查找示例,我终于完成了任务。我觉得在这里分享完整的任务,将来对开发者们会有所帮助。

Using the Code

现在我们直接进入代码。我将发布我的MVC控制器、HTML页面和JavaScript代码,并解释每个部分。

让我们创建一个Label类,该类具有用于标签尺寸的属性,称为LabelType

public class LabelType
{
    public string LabelTypeName;              //eg:Avery5160
    public int NoofLabelsperLine;
    public int NoofLines;
    public float LabelHeight;
    public float LabelWidth;
    public float LabelSpacingWidth;
    public float LabelSpacingHeight;
    public float LabelSpacingTop;
    public float LabelSpacingLeft;
    public Shape LabelShape;            //Rectangle,Round Rectangle,Circle

    public List<LabelItem> LabelItems;       //Dimensions for each field inside label 
                                             //(for name, address)
}

public class LabelItem : LabelAttribute
{
    public string LabelItemname;           
}

现在让我们创建一个类,用于label内部的每个字段,称为LabelItem

public class LabelItem : LabelAttribute
{
    public string LabelItemname;     //eg:Name,Address,Country
}

public class LabelAttribute
{
    public float HorizontalPosition;    //Position of field inside label in inches
    public float VerticalPosition;
    public string FontName;            //eg:Arial,Times New Roman
    public float FontSize;             //eg:8 pt,9 pt,10 pt
    public bool IsBoldApplied;     
    public bool IsItalicApplied;
    public bool IsActive;
}

这是shapeenum

public enum Shape
{
    Rectangle,
    RoundRectangle,
    Circle
}

以下是MVC控制器中用于设置标签尺寸的Post方法:

 [HttpPost]
        public JsonResult GetLabelType(string data, string option)
        {
            LabelType param = new JavaScriptSerializer().Deserialize<LabelType>(data);

            LabelType labelType = SetLabelType(option);

            labelType.LabelItems = new List<LabelItem>();

            for (int i = 0; i < 5; i++)
            {
                LabelItem labelItem = new LabelItem();
                switch (i)
                {
                    case 0:
                        labelItem.LabelItemname = "Dinesh Karthik";
                        break;
                    case 1:
                        labelItem.LabelItemname = "1st Street";
                        break;
                    case 2:
                        labelItem.LabelItemname = "Perungudi";
                        break;
                    case 3:
                        labelItem.LabelItemname = "Chennai";
                        break;
                    case 4:
                        labelItem.LabelItemname = "600103";
                        break;
                }
                labelItem.HorizontalPosition = param.LabelItems[i].HorizontalPosition * 96; 
                labelItem.VerticalPosition = param.LabelItems[i].VerticalPosition * 96;
                labelItem.FontName = param.LabelItems[i].FontName;
                labelItem.FontSize = param.LabelItems[i].FontSize;
                labelItem.IsBoldApplied = param.LabelItems[i].IsBoldApplied;
                labelItem.IsItalicApplied = param.LabelItems[i].IsItalicApplied;
                labelItem.IsActive = param.LabelItems[i].IsActive;
                if (labelItem.IsActive) labelType.LabelItems.Add(labelItem);
            }

            return new JsonResult 
              { Data = labelType, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
        }

位置乘以96进行英寸到像素的转换。

Setlabeltype函数的代码如下:

  private LabelType SetLabelType(string labelName)
        {
            LabelType labelType = new LabelType();
            
            switch (labelName)
            {
                case "lbAV5167":
                case "lbAV5267":
                case "lbAV5927":
                    labelType = SetLabelDims(0.5, 0.281, 0.5, 2.063, 0.5, 1.75, 4, 20);
                    break;                
                case "lbAV5295":
                    labelType = SetLabelDims(0.5, 0.625, 3.333, 3.937, 3.333, 3.333, 2, 3);
                    labelType.LabelShape = Shape.Circle;
                    break;
///Like this give for all label types
            }
            return labelType;
        }

SetLabelDims代码如下:

 private LabelType SetLabelDims(double SpacingTop, double SpacingLeft, 
double SpacingHeight, double SpacingWidth, 
   double LabelHeight, double LabelWidth, int NumAcross, int NumDown)
        {
            LabelType labelType = new LabelType();
            labelType.LabelSpacingTop = (float)SpacingTop * 96;
            labelType.LabelSpacingLeft = (float)SpacingLeft * 96;
            labelType.LabelSpacingHeight = (float)SpacingHeight * 96;
            labelType.LabelSpacingWidth = (float)SpacingWidth * 96;
            labelType.LabelHeight = (float)LabelHeight * 96;
            labelType.LabelWidth = (float)LabelWidth * 96;
            labelType.NoofLabelsperLine = NumAcross;
            labelType.NoofLines = NumDown;
            labelType.LabelShape = Shape.RoundRectangle;  //default is RoundRectangle
            return labelType;
        }

现在我们将查看HTML和JavaScript代码,用于该场景。

以下是用于用户更改标签尺寸的控件的HTML代码:

<div>
    <label>Name</label>
    <input id="isActiveName" type="checkbox" checked />
    <input id="horizontalName" 
    class="customwidth" value=".1" type="number" />
    <input id="verticalName" 
    class="customwidth" value=".25" type="number" />
    <select id="fontNameName"></select>
    <input id="fontSizeName" 
    class="customwidth" value="8" type="number" />
    <input id="checkBoldName" type="checkbox" />
    <input id="checkItalicName" type="checkbox" />
    
///Like the same give controls for Address 1,Address 2, City and Zip.

</div>

每个控件的ID将解释其用途,我认为不需要详细解释它们。

截图已附在Controls.png中。

现在我们将有两个canvas。一个用于外部div,其中包含数字标签,另一个是内部label

<canvas id="canvas1" 
style="border:1px solid #d3d3d3;background-color:white"></canvas>

<canvas id="canvas" 
style="border:1px solid #d3d3d3;display:none"></canvas>

label类型选择的下拉菜单如下:

<select id="Labels"></select>

下拉菜单绑定了label名称。我认为这段代码超出了本文的范围,因此避免在此处提供。

现在,我们将查看我们的JavaScript代码:

 var selectLabel = document.getElementById('Labels').value;

        var sample = {};
        var LabelSample = {};

        LabelSample.HorizontalPosition = document.getElementById("horizontalName").value;
        LabelSample.VerticalPosition = document.getElementById("verticalName").value;
        LabelSample.FontName = document.getElementById("fontNameName").value;
        LabelSample.FontSize = document.getElementById("fontSizeName").value;
        LabelSample.IsBoldApplied = $("#checkBoldName").prop('checked');
        LabelSample.IsItalicApplied = $("#checkItalicName").prop('checked');;
        LabelSample.IsActive = $("#isActiveName").prop('checked');
        sample.LabelItems = [LabelSample];

       ///Like the same get values from Address 1, Address 2,City and Zip

        sample = JSON.stringify(sample);

        $.ajax({
            type: 'POST',
            url: '/Home/GetLabelType',
            data: { data: sample, option: selectLabel },
            dataType: "json",
            async: false,
            success: function (data) {
                promise = data;

                var can = document.getElementById('canvas1');
                var ctx = can.getContext('2d');
                can.width = 816;     //width of a4 size paper
                can.height = 1056;  //height of a4 size paper

                var pattern = document.getElementById('canvas');

                var pctx = pattern.getContext('2d');
                pattern.width = Math.round(promise.LabelWidth);
                pattern.height = Math.round(promise.LabelHeight);

                for (i = 0; i < promise.LabelItems.length; i++) {
                    pctx.font = promise.LabelItems[i].FontSize + "pt " + promise.LabelItems[i].FontName;
                    if (promise.LabelItems[i].IsBoldApplied) {
                        pctx.font = "bold" + " " + pctx.font;
                    }
                    if (promise.LabelItems[i].IsItalicApplied) {
                        pctx.font = "italic" + " " + pctx.font;
                    }
                    pctx.fillText(promise.LabelItems[i].LabelItemname, 
                    promise.LabelItems[i].HorizontalPosition, promise.LabelItems[i].VerticalPosition);
                }

              //DRAW RECTANGE LABEL
                if (promise.LabelShape == "0") {
                    pctx.beginPath();
                    pctx.moveTo(0, 0);
                    pctx.lineTo(promise.LabelWidth, 0);
                    pctx.moveTo(promise.LabelWidth, 0);
                    pctx.lineTo(promise.LabelWidth, promise.LabelHeight);
                    pctx.moveTo(promise.LabelWidth, promise.LabelHeight);
                    pctx.lineTo(0, promise.LabelHeight);
                    pctx.moveTo(0, promise.LabelHeight);
                    pctx.lineTo(0, 0);
                    pctx.closePath();
                    pctx.stroke();
                }

               //DRAW CIRCLE LABEL
                else if (promise.LabelShape == "2") {
                    pctx.beginPath();
                    pctx.arc(promise.LabelWidth / 2, 
                    promise.LabelHeight / 2, promise.LabelWidth / 2, 0, 2 * Math.PI);
                    pctx.closePath();
                    pctx.stroke();
                }

              //DRAW ROUNDED RECTANGLE
                else {
                    pctx.beginPath();
                    pctx.moveTo(0 + 19.2, 0); //0.2 INCH ROUNDED CORNER IS CONVERTED TO 19.2 PX
                    pctx.lineTo(0 + promise.LabelWidth - 19.2, 0);
                    pctx.quadraticCurveTo(0 + promise.LabelWidth, 0, 0 + promise.LabelWidth, 0 + 19.2);
                    pctx.lineTo(0 + promise.LabelWidth, 0 + promise.LabelHeight - 19.2);
                    pctx.quadraticCurveTo(0 + promise.LabelWidth, 0 + 
                    promise.LabelHeight, 0 + promise.LabelWidth - 19.2, 0 + promise.LabelHeight);
                    pctx.lineTo(0 + 19.2, 0 + promise.LabelHeight);
                    pctx.quadraticCurveTo(0, 0 + promise.LabelHeight, 0, 0 + promise.LabelHeight - 19.2);
                    pctx.lineTo(0, 0 + 19.2);
                    pctx.quadraticCurveTo(0, 0, 0 + 19.2, 0);
                    pctx.lineWidth = .5;
                    pctx.closePath();
                    pctx.stroke();
                }

              //LOGIC FOR PRINTING LABELS INSIDE OUTER CANVAS

                var a = 0;
                var b = 0;
                for (i = 1; i <= promise.NoofLines; i++) {
                    for (j = 1; j <= promise.NoofLabelsperLine; j++) {
                        a = ((j - 1) * promise.LabelSpacingWidth + promise.LabelSpacingLeft);
                        b = ((i - 1) * promise.LabelSpacingHeight + promise.LabelSpacingTop);
                        ctx.drawImage(pattern, a, b, promise.LabelWidth, promise.LabelHeight);
                    }
                }
            }
        })
    }

我认为代码不言自明,因此没有解释每一行代码。

  • 我没有使用Canvaspattern,因为在模式之间提供均匀的间距比较困难。
  • 我在网上查找并获得了Canvas中绘制圆角矩形的代码。
  • 将复选框值转换为布尔值需要使用prop('checked')函数。
  • 我在这个项目的开发过程中遇到了很多困难。我已经整合了所有这些,并在此呈现。
  • 我没有在HTML中正确对齐任何控件,因为这只是一个示例,我认为逻辑更重要,因为它不是为最终用户设计的。

我已将标签模式截图附在Label_Pattern.png文件中。

如有任何疑问,请发表评论。

历史

  • 2014年11月19日:初始版本
© . All rights reserved.