<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      WizardWu 編程網(wǎng)

      一位臺(tái)灣的工程師,接觸 .NET 逾十年,近年研究 SQL Server、Performance Tuning、手機(jī)應(yīng)用

      博客園 首頁(yè) 新隨筆 聯(lián)系 訂閱 管理

      教導(dǎo)如何用 C# 創(chuàng)建 Code 39 編碼的「條碼 (barcode)」圖片,以供 ASP.NET + Crystal Reports 水晶報(bào)表呈現(xiàn)和打印此條碼。本帖提供 ASP.NET 3.5 示例下載。

      -------------------------------------------------
      本帖的示例下載點(diǎn):
      https://files.cnblogs.com/WizardWu/100914.zip

      執(zhí)行本示例,需要 SQL Server 的 Northwind 數(shù)據(jù)庫(kù),以及 VS 2008 或 IIS,另還需要 Crystal Reports 2008 標(biāo)準(zhǔn)版 (SAP 公司的網(wǎng)站可下載完整的安裝程序,無(wú)使用限制,但安裝前需要輸入安裝序列號(hào))。
      若是 VS 2005/2008 內(nèi)置的免費(fèi)簡(jiǎn)易版 Crystal Reports,由于不具備「動(dòng)態(tài)截取網(wǎng)絡(luò)圖片」的功能、無(wú)法抓取既有的條碼圖片,因此不適用本帖的教學(xué)。
      ---------------------------------------------------

      日前做 ASP.NET 的項(xiàng)目用到 Crystal Reports 水晶報(bào)表,必須要能在瀏覽器中的報(bào)表顯示和打印條碼。原本我采用「字體 (font)」的方式產(chǎn)生條碼 (水晶報(bào)表內(nèi)置將某個(gè)數(shù)據(jù)庫(kù)字段,直接轉(zhuǎn)成條形碼的功能),但后來(lái)發(fā)現(xiàn)這種做法,布署時(shí)必須在每一臺(tái)客戶(hù)端的 Windows 上安裝特定的條碼字體,如:free3of9 (可免費(fèi)下載),才能在客戶(hù)端瀏覽器正確顯示和打印條碼。因此后來(lái)?xiàng)売眠@種做法,改用「圖片」的方式產(chǎn)生條碼。

      做法是先用 C# 和 .NET 的繪圖 API,搭配一維條碼最普遍的 Code 39 編碼其規(guī)則,寫(xiě)一個(gè)可創(chuàng)建條碼圖片的 .ashx (HttpHandler) 或 .aspx,(這個(gè)文件放在報(bào)表的同一個(gè) ASP.NET 項(xiàng)目里即可,不必發(fā)布成 service)。接著在 Crystal Reports 文件里,隨便插入一張圖片,透過(guò)水晶報(bào)表標(biāo)準(zhǔn)版才有的「動(dòng)態(tài)截取網(wǎng)絡(luò)圖片」功能 (Visual Studio 內(nèi)置的免費(fèi)版水晶報(bào)表無(wú)此功能),去抓取這張已創(chuàng)建的條碼圖片,并要能動(dòng)態(tài)傳入?yún)?shù),以讓報(bào)表在換頁(yè)時(shí),條碼可跟著變動(dòng)內(nèi)容。


      首先用 C# 和 .NET 的繪圖 API,搭配 Code 39 條碼的編碼規(guī)則,寫(xiě)一個(gè)可創(chuàng)建條碼圖片的組件。請(qǐng)參考本帖的下載示例,直接用瀏覽器開(kāi)啟 Code39Handler.ashx,并透過(guò)瀏覽器的 URL 地址欄,手動(dòng)輸入條碼的參數(shù)作測(cè)試。執(zhí)行結(jié)果和源代碼 (這種組件通常是要錢(qián)的) 如下:



      圖 1 用 C# 和 .NET 的繪圖 API,搭配 Code 39 編碼規(guī)則產(chǎn)生的條碼圖片


      以下代碼,是用 C# 和 .NET 的繪圖 API,搭配 Code 39 編碼規(guī)則產(chǎn)生條碼圖片 (原版 VB 版作者為臺(tái)灣的 阿達(dá)猴)。

      Code39Handler
      <%@ WebHandler Language="C#" Class="Code39Handler" %>

      using System;
      using System.Web;
      using System.Drawing;
      using System.Drawing.Imaging;
      using System.Drawing.Text;

      /// <summary>
      /// 用 .NET 繪圖 API,搭配條碼最普遍的 Code 39 編碼規(guī)則 (一般超商的讀條碼機(jī)都可讀),產(chǎn)生條碼圖檔
      /// </summary>
      public class Code39Handler : IHttpHandler {
          
          
      public void ProcessRequest (HttpContext context) {
              
      //context.Response.ContentType = "text/plain";
              
      //context.Response.Write("Hello World");

              
      //Logic to retrieve the image file
              
      //context.Response.ContentType = "image/jpeg";
              
      //context.Response.WriteFile("MyImage01.jpg");

              
      string mycode = context.Request["code"];

              
      string 字串;
              
      string 字元;
              
      //字串 = "*-%$*"
              字串 = "*" + mycode + "*";  //Code 39 的特性是前、後置碼會(huì)標(biāo)識(shí)「星號(hào)(*)」,表示開(kāi)始和結(jié)束

              
      int 畫(huà)布高 = 35;
              
      int 畫(huà)布寬 = 0;
              
      int 筆x = 0;
              
      int 筆y = 20;
              
      //int 筆寬 = 0;
              
              
      if (!string.IsNullOrEmpty(mycode))
              {
                  畫(huà)布寬 
      = 字串.Length * 13;

                  Bitmap BMP 
      = new Bitmap(畫(huà)布寬, 畫(huà)布高, System.Drawing.Imaging.PixelFormat.Format32bppPArgb);
                  Graphics G 
      = Graphics.FromImage(BMP);
                  G.TextRenderingHint 
      = TextRenderingHint.AntiAlias;
                  G.Clear(Color.White);

                  Brush 筆刷1 
      = new SolidBrush(Color.White);
                  G.SmoothingMode 
      = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
                  G.FillRectangle(筆刷1, 
      00, 畫(huà)布寬, 畫(huà)布高);

                  
      for (int i = 0; i < 字串.Length; i++)
                  {
                      
      //取得 Code 39 碼的規(guī)則
                      字元 = this.genBarcode(字串.Substring(i, 1).ToUpper());

                      
      for (int j = 0; j < 4; j++)
                      {
                          
      if (字元.Substring(j, 1).Equals("0"))
                          {
                              G.DrawLine(Pens.Black, 筆x, 
      0, 筆x, 筆y);
                          }
                          
      else
                          {
                              G.DrawLine(Pens.Black, 筆x, 
      0, 筆x, 筆y);
                              G.DrawLine(Pens.Black, 筆x 
      + 10, 筆x + 1, 筆y);
                              筆x 
      += 1;
                          }

                          筆x 
      += 1;

                          
      if (字元.Substring(j + 51).Equals("0"))
                          {
                              G.DrawLine(Pens.White, 筆x, 
      0, 筆x, 筆y);
                          }
                          
      else
                          {
                              G.DrawLine(Pens.White, 筆x, 
      0, 筆x, 筆y);
                              G.DrawLine(Pens.White, 筆x 
      + 10, 筆x + 1, 筆y);
                              筆x 
      += 1;
                          }

                          筆x 
      += 1;
                      } 
      //end of loop

                      
      if (字元.Substring(41).Equals("0"))
                      {
                          G.DrawLine(Pens.Black, 筆x, 
      0, 筆x, 筆y);
                      }
                      
      else
                      {
                          G.DrawLine(Pens.Black, 筆x, 
      0, 筆x, 筆y);
                          G.DrawLine(Pens.Black, 筆x 
      + 10, 筆x + 1, 筆y);
                          筆x 
      += 1;
                      }

                      筆x 
      += 2;
                  } 
      //end of loop

                  
      int x = 0;
                  
      int addx = 13;

                  G.DrawString(
      "-"new Font("Arial"10, FontStyle.Italic), SystemBrushes.WindowText, new PointF(x, 20));
                  x 
      += addx;

                  
      for (int k = 0; k < mycode.Length; k++)
                  {
                      G.DrawString(mycode.Substring(k, 
      1), new Font("Arial"10, FontStyle.Italic), SystemBrushes.WindowText, new PointF(x, 20));
                      x 
      = x + addx;
                  }

                  G.DrawString(
      "-"new Font("Arial"10, FontStyle.Italic), SystemBrushes.WindowText, new PointF(x, 20));
                  BMP.Save(context.Response.OutputStream, ImageFormat.Jpeg);
                  G.Dispose();
                  BMP.Dispose();

              }
              
      else
              {
                  畫(huà)布寬 
      = 100;

                  Bitmap BMP 
      = new Bitmap(畫(huà)布寬, 畫(huà)布高, System.Drawing.Imaging.PixelFormat.Format32bppPArgb);
                  Graphics G 
      = Graphics.FromImage(BMP);
                  G.TextRenderingHint 
      = TextRenderingHint.AntiAlias;
                  G.Clear(Color.White);
                  
                  
      //未給參數(shù)時(shí)顯示的提示內(nèi)容
                  G.DrawString("無(wú)條碼產(chǎn)生"new Font("宋體"12, FontStyle.Regular), SystemBrushes.WindowText, new PointF(020));

                  BMP.Save(context.Response.OutputStream, ImageFormat.Jpeg);
                  G.Dispose();
                  BMP.Dispose();
              }
          }


          
      // 規(guī)則可參考網(wǎng)址 1:http://blog.csdn.net/xuzhongxuan/archive/2008/05/28/2489358.aspx
          
      // 規(guī)則可參考網(wǎng)址 2:http://blog.163.com/zryou/blog/static/6903184200971704226450/
          /// <summary>
          
      /// Code 39 碼的規(guī)則。
          
      /// Code 39 碼可使用的字元如下:0~9、A~Z、+、-、*、/、%、$、. 及空白字元。    
          
      /// </summary>
          
      /// <param name="code"></param>
          
      /// <returns></returns>
          public string genBarcode(string code)
          {
              
      switch (code)
              {
                  
      case "0":
                      code 
      = "001100100";
                      
      break;
                  
      case "1":
                      code 
      = "100010100";
                      
      break;
                  
      case "2":
                      code 
      = "010010100";
                      
      break;
                  
      case "3":
                      code 
      = "110000100";
                      
      break;
                  
      case "4":
                      code 
      = "001010100";
                      
      break;
                  
      case "5":
                      code 
      = "101000100";
                      
      break;
                  
      case "6":
                      code 
      = "011000100";
                      
      break;
                  
      case "7":
                      code 
      = "000110100";
                      
      break;
                  
      case "8":
                      code 
      = "100100100";
                      
      break;
                  
      case "9":
                      code 
      = "010100100";
                      
      break;
                  
      case "A":
                      code 
      = "100010010";
                      
      break;
                  
      case "B":
                      code 
      = "010010010";
                      
      break;
                  
      case "C":
                      code 
      = "110000010";
                      
      break;
                  
      case "D":
                      code 
      = "001010010";
                      
      break;
                  
      case "E":
                      code 
      = "101000010";
                      
      break;
                  
      case "F":
                      code 
      = "011000010";
                      
      break;
                  
      case "G":
                      code 
      = "000110010";
                      
      break;
                  
      case "H":
                      code 
      = "100100010";
                      
      break;
                  
      case "I":
                      code 
      = "010100010";
                      
      break;
                  
      case "J":
                      code 
      = "001100010";
                      
      break;
                  
      case "K":
                      code 
      = "100010001";
                      
      break;
                  
      case "L":
                      code 
      = "010010001";
                      
      break;
                  
      case "M":
                      code 
      = "110000001";
                      
      break;
                  
      case "N":
                      code 
      = "001010001";
                      
      break;
                  
      case "O":
                      code 
      = "101000001";
                      
      break;
                  
      case "P":
                      code 
      = "011000001";
                      
      break;
                  
      case "Q":
                      code 
      = "000110001";
                      
      break;
                  
      case "R":
                      code 
      = "100100001";
                      
      break;
                  
      case "S":
                      code 
      = "010100001";
                      
      break;
                  
      case "T":
                      code 
      = "001100001";
                      
      break;
                  
      case "U":
                      code 
      = "100011000";
                      
      break;
                  
      case "V":
                      code 
      = "010011000";
                      
      break;
                  
      case "W":
                      code 
      = "110001000";
                      
      break;
                  
      case "X":
                      code 
      = "001011000";
                      
      break;
                  
      case "Y":
                      code 
      = "101001000";
                      
      break;
                  
      case "Z":
                      code 
      = "011001000";
                      
      break;
                  
      case "*":
                      code 
      = "001101000";
                      
      break;
                  
      case "-":
                      code 
      = "000111000"//好像辨識(shí)不出來(lái)
                      break;
                  
      case "%":
                      code 
      = "100101000"//好像辨識(shí)不出來(lái)
                      break;
                  
      case "$":
                      code 
      = "010101000"//好像辨識(shí)不出來(lái)
                      break;
                  
      default:
                      code 
      = "010101000"//都不是就印 $
                      break;
              }
              
              
      return code;
          }
          
       
          
      public bool IsReusable {
              
      get {
                  
      return false;
              }
          }

      }

       

      執(zhí)行 Default.aspx 里的水晶報(bào)表,結(jié)果如下圖 2。條碼是圖片,不是字體,不必?fù)?dān)心客戶(hù)端的瀏覽器或打印機(jī)無(wú)法辨識(shí)某種條碼字體。另下圖 2 里,Employees 表的 EmployeeID 字段在數(shù)據(jù)庫(kù)里是 int 類(lèi)型,其傳遞至水晶報(bào)表默認(rèn)會(huì)被當(dāng)作 Number 類(lèi)型,而自動(dòng)顯示小數(shù)點(diǎn)及后兩位數(shù)字。本文后續(xù)會(huì)提到此問(wèn)題的解法。



      圖 2 報(bào)表?yè)Q頁(yè)時(shí),會(huì)傳入不同的參數(shù)內(nèi)容到我們寫(xiě)的條碼組件里,因此條碼內(nèi)容也會(huì)跟著變動(dòng)


      若您想測(cè)試本帖示例,可去 SAP 公司的官方網(wǎng)站,下載標(biāo)準(zhǔn)版的 Crystal Reports 2008 軟件 (下載頁(yè)面標(biāo)識(shí)的 Service Pack 版或 V1 版,若文件大小有 300 多至 500 多 MB,表示已內(nèi)置安裝主程序 + 修補(bǔ)程序,并非只有修補(bǔ)程序)。該軟件和 Oracle 數(shù)據(jù)庫(kù)的策略一樣,提供網(wǎng)絡(luò)下載完整的安裝主程序、無(wú)使用時(shí)間限制或功能限制,但安裝 Crystal Reports 前需要輸入序列號(hào) (怎么找序列號(hào)本文不贅述)。安裝過(guò)程如下圖 3,應(yīng)加選「數(shù)據(jù)訪問(wèn)」的 ADO.NET 功能,以配合本帖示例的 ASP.NET 報(bào)表做法,透過(guò)網(wǎng)站 App_Code 文件夾里,事先定義好要訪問(wèn)的數(shù)據(jù)庫(kù)內(nèi)容的 .xsd (DataSet) 文件,作為設(shè)計(jì) Crystal Reports 報(bào)表時(shí)的數(shù)據(jù)來(lái)源 (.xsd 為 XML 文件,這里面會(huì)依您寫(xiě)的 SQL 語(yǔ)句,了解報(bào)表要訪問(wèn)哪些表的哪些字段)。



      圖 3 Crystal Reports 2008 安裝過(guò)程,加選「數(shù)據(jù)訪問(wèn)」的 ADO.NET 選項(xiàng)


      如下圖 4、圖 5,在新建的水晶報(bào)表文件里,隨便插入一個(gè)圖片,在上面單擊右鍵選擇「設(shè)置圖形格式」,再選擇 Crystal Reports 標(biāo)準(zhǔn)版才有的「圖形位置」功能。



      圖 4 在水晶報(bào)表里先隨便插入一張圖片



      圖 5 Crystal Reports 標(biāo)準(zhǔn)版才有的「圖形位置」功能,VS 2005/2008 內(nèi)置的版本無(wú)此功能


      如下圖 6,在水晶報(bào)表的「公式編輯器」里,輸入以下內(nèi)容和參數(shù)。此處動(dòng)態(tài)傳入的參數(shù),會(huì)傳入上圖 1 里,我們事先用 C# 寫(xiě)好的條碼生成組件。此例中,參數(shù)內(nèi)容是 Employees 表的 EmployeeID 字段。若您報(bào)表里的條碼,無(wú)法正確透過(guò)瀏覽器呈現(xiàn),多半是這里的地址、端口號(hào)或內(nèi)容打錯(cuò),或此創(chuàng)建條碼的服務(wù)未正確啟用,此時(shí)瀏覽器只會(huì)顯示原始插入報(bào)表的圖片,而非條碼。

      下圖 6、圖 7 的公式編輯器里,及本帖提供的下載示例,在引用 Code39Handler.ashx 時(shí)站點(diǎn)的 URL 是硬編碼的絕對(duì)路徑,但我們可以改成動(dòng)態(tài)賦值,如下:
      "http://" & {?param1} & "/Code39Handler.ashx?code=" & {Employees.EmployeeID}

      其中 ?param1 是我們從 ASP.NET Code-Behind,以 C# 傳入的參數(shù)。我們可先用 C# 取得 Web server 機(jī)器的 IP 或 Domain Name,將其以字符串參數(shù)的方式,傳入水晶報(bào)表的公式里,即可動(dòng)態(tài)賦值,無(wú)須硬編碼將 IP 寫(xiě)死在水晶報(bào)表的公式里。


      圖 6 公式編輯器里的語(yǔ)法,較類(lèi)似 VB 或 VB.NET


      另在上圖 2 里,我們提到 EmployeeID 字段,在數(shù)據(jù)庫(kù)里的類(lèi)型是 int,在水晶報(bào)表里會(huì)被當(dāng)作 Number 類(lèi)型,而在條碼里自動(dòng)加上小數(shù)點(diǎn)及后兩位數(shù)字。解決方式如下圖 7,用 水晶報(bào)表自帶的 CStr 函數(shù),將該字段轉(zhuǎn)型成字符串即可。



      圖 7 若報(bào)表里的條碼,無(wú)法正確透過(guò)瀏覽器呈現(xiàn),多半是這里的地址或內(nèi)容打錯(cuò),或這里未改成您 VS 2008 內(nèi)置 Web server 或 IIS 執(zhí)行時(shí)的正確地址、端口號(hào)


      本文介紹的這種圖片條碼的做法,不只適用于 Crystal Reports 報(bào)表軟件才能引用。理論上,其他廠牌的報(bào)表軟件、網(wǎng)頁(yè)程序,只要能鏈接至這個(gè)掛在 IIS 上提供服務(wù)的 Code39Handler.ashx 組件,就能在各自的報(bào)表或網(wǎng)頁(yè)中,呈現(xiàn)此圖片條碼以供瀏覽和打印。


      附帶一提,在布署 ASP.NET 水晶報(bào)表至 IIS 時(shí),必須將 IIS 默認(rèn)目錄:
      C:\Inetpub\wwwroot\
      底下的 aspnet_client 文件夾和里面的文件 (圖 8),一并拷貝至我們的 ASP.NET 網(wǎng)站底下 (圖 9),這樣透過(guò) IIS 執(zhí)行的水晶報(bào)表,才能正確顯示報(bào)表 Toolbar 里的 icon 按鈕,并正確展示相關(guān)的功能。


      圖 8 此文件夾在安裝完 Crystal Reports 主程序后,內(nèi)容會(huì)自動(dòng)增加



      圖 9 ASP.NET 網(wǎng)站布署至 IIS 時(shí),必須一并將 aspnet_client 文件夾拷貝至網(wǎng)站的根目錄

       

      順便提醒,水晶報(bào)表的打印方式分兩種,一是透過(guò)報(bào)表 Toolbar 自帶的打印按鈕 (參考上圖 2),二是自己撰碼調(diào)用 ReportDocument 類(lèi)的 PrintToPrinter 方法。

      第一種打印方式,才能突破瀏覽器的安全限制,自動(dòng)下載 ActiveX 程序以呈現(xiàn)打印預(yù)覽的窗體,并能自動(dòng)抓取到客戶(hù)端的打印機(jī)名稱(chēng)。這種做法適合跨互聯(lián)網(wǎng)打印,或需要在各自辦公室里打印的用戶(hù)。
      第二種打印方式,雖然程序客制能力較強(qiáng),但只能抓取服務(wù)器端的打印機(jī)名稱(chēng),因此報(bào)表只能在服務(wù)器端打印或生成 PDF 文件。這種做法只適合同一個(gè) LAN 或近距離 Intranet 共用打印機(jī)的用戶(hù)。 
       

      posted on 2010-09-14 03:19  WizardWu  閱讀(13842)  評(píng)論(27)    收藏  舉報(bào)
      主站蜘蛛池模板: 亚洲 制服 丝袜 无码| 国产va免费精品观看| 97人人模人人爽人人喊网| 亚洲人成亚洲人成在线观看| 女人腿张开让男人桶爽| 久久综合久中文字幕青草| 国产午夜福利在线机视频 | 婷婷综合亚洲| 久章草在线毛片视频播放| 欧美裸体xxxx极品| 大香伊蕉在人线国产最新2005| 亚洲熟妇自偷自拍另类| 天堂网www在线资源网| 午夜福利院一区二区三区| 亚洲人午夜精品射精日韩| 美女一区二区三区亚洲麻豆| 超碰成人人人做人人爽| 国产办公室秘书无码精品99| 欧美嫩交一区二区三区| 精品国产亚洲第一区二区三区| 国产av综合影院| 深田えいみ禁欲后被隔壁人妻| 国产女主播喷水视频在线观看| 亚洲综合91社区精品福利| 亚洲精品国产第一区二区| 亚洲精品一二三四区| 人妻另类 专区 欧美 制服| 伊人天天久大香线蕉av色| 国产妇女馒头高清泬20p多毛| 亚洲精品综合网二三区| 国产精品美女www爽爽爽视频| 国产精品久久久久乳精品爆| 亚洲日本欧洲二区精品| 成人精品久久一区二区三区| 婷婷成人丁香五月综合激情| 人人狠狠综合久久亚洲爱咲| 中文字幕av无码不卡| 黄骅市| 又大又紧又粉嫩18p少妇| 欧美激情内射喷水高潮| 国产最大的福利精品自拍|