生成员工卡

时间:2015-02-17 10:54:28

标签: c# drawing

我们公司希望为员工打印员工卡,因此我们准备了一个模板,其中包含每个人的照片,姓名和部门的占位符。
我们有一个数据库表,其中包括每个人的照片,名称和部门的路径。
我想知道是否有可能遍历该表并将人员数据添加到卡模板中并保存 我使用的是C#.Net,但如果您因此而知道更好的解决方案,我很乐意倾听。

preview of card template

2 个答案:

答案 0 :(得分:4)

使用C#和GDI +

完全没问题

以下是简短版本:

  1. 创建正确尺寸和分辨率的Bitmap
  2. 测量您想要的图像和文本的坐标
  3. 从数据库中提取数据
  4. 使用Graphics.DrawImageGraphics.DrawString创建图片
  5. 以您喜欢的格式保存,最好是PNG,因为这样可以保持文字清晰
  6. 详细信息如下:

    1. 您需要计算图片应该有多少像素。由于您希望能够打印它,您应该使用至少150dpi或200dpi。
    2. 您发布的图片没有DPI设置和1004x638像素;将其设置为150dpi会导致物理尺寸为170x108 mm。我们假设这没关系..

      所以我们用这些参数创建一个位图:

      Size keyCardSize = new Size (1004, 63);
      float Dpi = 150f;
      Bitmap bmp = new Bitmap(keyCardSize.Width, keyCardSize.Height);
      bmp.SetResolution(Dpi, Dpi);
      
      1. 以下代码将以毫米为单位。您可能希望将其更改为其他内容。
      2. 查看您的模板,我们会看到6个图像(徽标,照片和4个图标)和7个文本块(名称,位置,部门和四个联系人文本)。

        使用Graphics G绘制图像或文本的基本命令如下所示:

           G.DrawImage(bitmap, location);
           G.DrawString(text, font, brush, location);
        

        在我们的情况下,这对于徽标和照片工作正常,因为它们是左对齐的。您需要做的就是测量位置并创建位置点。确保 以正确的尺寸和分辨率创建适合dpi的图像,以弥补不同的像素大小!

        更新:我添加了代码以调整照片dpi以使宽度适合模板中的30mm帧。这假设比例是正确的和/或我们更关心宽度而不是高度。如果我们需要匹配两者,要么得到正确的比例要么要求裁剪代码; - )

        测量其余的项目有点复杂,因为它们都是正确对齐的。以下是如何为字符串txt1执行此操作的示例:

        SizeF s1 = G.MeasureString(txt1, font1, PointF.Empty, StringFormat.GenericTypographic);
        G.DrawString(txt1, font1, brush1, new Point((int)(rightBorder - s1.Width), y1));
        

        您可以(并且必须)衡量每个位置的顶部(Y),但左侧(X)必须像上面那样计算!

        请注意,您需要告诉测量命令您要使用的字体;忽略其他参数!在测量右边界后,这些命令将与必要的数据和图形对象一起正常工作..

        1. 从数据库中提取数据。我想你可以做到!我进一步假设你可以改变&展开下面的代码以填充数据字段,并使filename动态显示您的记录..
        2. 4和5。请参阅此代码示例:


           private void Button_Click(object sender, EventArgs e)
           {
              string FontFamily = "Verdana";
          
              string fileName = "d:\\template.png";
          
              Size keyCardSize = new Size (1004, 638); // 170x108mm
              float Dpi = 150f;
              Bitmap bmp = new Bitmap(keyCardSize.Width, keyCardSize.Height);
              bmp.SetResolution(Dpi, Dpi);
          
              // test data:
              Bitmap photo = new Bitmap(@"D:\scrape\sousers\SOU_JonSkeet.jpeg");
              // I have measured the photo should be 30mm wide
              // so with 25.4mm to the inch we calculate a fitting dpi for it:  
              float photoDpi = photo.Width * 25.4f / 30f;
              photo.SetResolution(photoDpi , photoDpi );
          
              Font font1 = new Font(FontFamily, 23f);
              Font font2 = new Font(FontFamily, 12f);
              Font font3 = new Font(FontFamily, 14f);
          
              using (Graphics G = Graphics.FromImage(bmp))
              using (SolidBrush brush1 = new SolidBrush(Color.MediumVioletRed))
              using (SolidBrush brush2 = new SolidBrush(Color.Gray))
              {
                  G.Clear(Color.White);
                  G.InterpolationMode = InterpolationMode.HighQualityBicubic;
                  G.PageUnit = GraphicsUnit.Millimeter;
                  G.SmoothingMode = SmoothingMode.HighQuality;
          
                  StringFormat sf = StringFormat.GenericTypographic;
          
                  int lBorder= 10;
                  int rBorder= 160;
                  int y1 = 10;
                  int y2 = 25;
                  //..
                  int y4 = 60;
                  //..
                  //G.DrawImage(logo, imgLoc1);
                  G.DrawImage(photo, new Point(lBorder, y4));
                  //G.DrawImage(img3, imgLoc3);
                  //G.DrawImage(img4, imgLoc4);
                  //G.DrawImage(img5, imgLoc5);
          
          
                 // test data:
                  string txt1 = "Jon Skeet";
                  string txt2 = "C Sharp Evangelist";
                  //..
          
                  SizeF s1 = G.MeasureString(txt1, font1, PointF.Empty, sf);
                  SizeF s2 = G.MeasureString(txt2, font2, PointF.Empty, sf);
                  //..
          
                  G.DrawString(txt1, font1, brush1, new Point((int)(rBorder- s1.Width), y1));
                  G.DrawString(txt2, font2, brush2, new Point((int)(rBorder- s2.Width), y2));
          
                  //G.DrawString(txt3, font2, brush2, txtLoc3);
                  //..
                  //G.DrawString(txt7, font3, brush2, txtLoc7);
          
                  G.FillRectangle(brush1, new RectangleF(rBorder - 1.5f, 52f, 1.5f, 46f));
          
            }
          
            bmp.Save(fileName, ImageFormat.Png);
          
            font1.Dispose();
            font2.Dispose();
            font3.Dispose();
          
            photo.Dispose();
            //..
          }
          

          我希望这会让你前进。如果您有任何疑问,请随时询问..

          以下是基本结果:

          enter image description here

          事后的想法:您可能希望通过使用模板作为开始来简化整个代码:您可以将徽标,图标和垂直条都放在适当的位置,只需要绘制一个图像和文本......!

答案 1 :(得分:0)

好吧,只是一个想法可能不起作用,但我想我会抛出一些东西来帮助它们!

如何创建一个像你说的那样循环数据库的程序。但是对于Staff卡,创建一个像GraphicsBox一样的用户界面,以及一些文本框;在Ui上创建/使用打印功能,使窗口无边框以进行打印输出。

我不确定这是否会起作用,因为我使用C ++并且从未真正想过做这样的事情,但我从头脑中得到了这个以前你永远都不知道!

但是你会明显地印刷到我认为的高质量塑料上,还是会被层压?这不是真正重要的事情:)