条码(code128)的不同版本实现

好久没写Blog了,这次写写条码(code128)打印的实现。条码在工业应用方面很广泛,所以我们在编写程序时,特别是打印报表时,经常用到。

#region "本段为转载"  转自:http://kaliking.blog.51cto.com/58641/33734

先简述一下CODE128的原理吧,分别以一个unicode字符作为起始符(Ì)和终止符(Î),

然后需要根据你的字符串, 计算出当前字符集的校验码:

 

 ode 128 Barcode Table

Value

Code Set A

Code Set B

Code Set C

Bar/Space Pattern B S B S B S

0

SP

SP

00

2 1 2 2 2 2

1

!

!

01

2 2 2 1 2 2

2

"

"

02

2 2 2 2 2 1

3

#

#

03

1 2 1 2 2 3

4

$

$

04

1 2 1 3 2 2

5

%

%

05

1 3 1 2 2 2

6

&

&

06

1 2 2 2 1 3

7

'

'

07

1 2 2 3 1 2

8

(

(

08

1 3 2 2 1 2

9

)

)

09

2 2 1 2 1 3

10

*

*

10

2 2 1 3 1 2

11

+

+

11

2 3 1 2 1 2

12

,

,

12

1 1 2 2 3 2

13

-

-

13

1 2 2 1 3 2

14

.

.

14

1 2 2 2 3 1

15

/

/

15

1 1 3 2 2 2

16

0

0

16

1 2 3 1 2 2

17

1

1

17

1 2 3 2 2 1

18

2

2

18

2 2 3 2 1 1

19

3

3

19

2 2 1 1 3 2

20

4

4

20

2 2 1 2 3 1

21

5

5

21

2 1 3 2 1 2

22

6

6

22

2 2 3 1 1 2

23

7

7

23

3 1 2 1 3 1

24

8

8

24

3 1 1 2 2 2

25

9

9

25

3 2 1 1 2 2

26

:

:

26

3 2 1 2 2 1

27

;

;

27

3 1 2 2 1 2

28

<

<

28

3 2 2 1 1 2

29

=

=

29

3 2 2 2 1 1

30

>

>

30

2 1 2 1 2 3

31

?

?

31

2 1 2 3 2 1

32

@

@

32

2 3 2 1 2 1

33

A

A

33

1 1 1 3 2 3

34

B

B

34

1 3 1 1 2 3

35

C

C

35

1 3 1 3 2 1

36

D

D

36

1 1 2 3 1 3

37

E

E

37

1 3 2 1 1 3

38

F

F

38

1 3 2 3 1 1

39

G

G

39

2 1 1 3 1 3

40

H

H

40

2 3 1 1 1 3

41

I

I

41

2 3 1 3 1 1

42

J

J

42

1 1 2 1 3 3

43

K

K

43

1 1 2 3 3 1

44

L

L

44

1 3 2 1 3 1

45

M

M

45

1 1 3 1 2 3

46

N

N

46

1 1 3 3 2 1

47

O

O

47

1 3 3 1 2 1

48

P

P

48

3 1 3 1 2 1

49

Q

Q

49

2 1 1 3 3 1

50

R

R

50

2 3 1 1 3 1

51

S

S

51

2 1 3 1 1 3

52

T

T

52

2 1 3 3 1 1

53

U

U

53

2 1 3 1 3 1

54

V

V

54

3 1 1 1 2 3

55

W

W

55

3 1 1 3 2 1

56

X

X

56

3 3 1 1 2 1

57

Y

Y

57

3 1 2 1 1 3

58

Z

Z

58

3 1 2 3 1 1

59

[

[

59

3 3 2 1 1 1

60

/

/

60

3 1 4 1 1 1

61

]

]

61

2 2 1 4 1 1

62

^

^

62

4 3 1 1 1 1

63

_

_

63

1 1 1 2 2 4

64

NUL

`

64

1 1 1 4 2 2

65

SOH

a

65

1 2 1 1 2 4

66

STX

b

66

1 2 1 4 2 1

67

ETX

c

67

1 4 1 1 2 2

68

EOT

d

68

1 4 1 2 2 1

69

ENQ

e

69

1 1 2 2 1 4

70

ACK

f

70

1 1 2 4 1 2

71

BEL

g

71

1 2 2 1 1 4

72

BS

h

72

1 2 2 4 1 1

73

HT

i

73

1 4 2 1 1 2

74

LF

j

74

1 4 2 2 1 1

75

VT

k

75

2 4 1 2 1 1

76

FF

I

76

2 2 1 1 1 4

77

CR

m

77

4 1 3 1 1 1

78

SO

n

78

2 4 1 1 1 2

79

SI

o

79

1 3 4 1 1 1

80

DLE

p

80

1 1 1 2 4 2

81

DC1

q

81

1 2 1 1 4 2

82

DC2

r

82

1 2 1 2 4 1

83

DC3

s

83

1 1 4 2 1 2

84

DC4

t

84

1 2 4 1 1 2

85

NAK

u

85

1 2 4 2 1 1

86

SYN

v

86

4 1 1 2 1 2

87

ETB

w

87

4 2 1 1 1 2

88

CAN

x

88

4 2 1 2 1 1

89

EM

y

89

2 1 2 1 4 1

90

SUB

z

90

2 1 4 1 2 1

91

ESC

{

91

4 1 2 1 2 1

92

FS

|

92

1 1 1 1 4 3

93

GS

}

93

1 1 1 3 4 1

94

RS

~

94

1 3 1 1 4 1

95

US

DEL

95

1 1 4 1 1 3

96

FNC 3

FNC 3

96

1 1 4 3 1 1

97

FNC 2

FNC 2

97

4 1 1 1 1 3

98

SHIFT

SHIFT

98

4 1 1 3 1 1

99

CODE C

CODE C

99

1 1 3 1 4 1

100

CODE B

FNC 4

CODE B

1 1 4 1 3 1

101

FNC 4

CODE A

CODE A

3 1 1 1 4 1

102

FNC 1

FNC 1

FNC 1

4 1 1 1 3 1

103

Start A

Start A

Start A

2 1 1 4 1 2

104

Start B

Start B

Start B

2 1 1 2 1 4

105

Start C

Start C

Start C

2 1 1 2 3 2

106

Stop

Stop

Stop

2 3 3 1 1 1 2

 

 

 

Example... To calculate the check digit for the barcode data string 'Code 128'

                              Value                  Total
                              =====                  =====
             Start Code B      104                    104
Position 1              C       35         1 x 35 =    35
Position 2              o       79         2 x 79 =   158
Position 3              d       68         3 x 68 =   204
Position 4              e       69         4 x 69 =   276
Position 5                       0         5 x  0 =     0
Position 6              1       17         6 x 17 =   102
Position 7              2       18         7 x 18 =   126
Position 8              8       24         8 x 24 =   192
                                                     =====
                                                     1197
                                                     =====
             1197/103 = 11 remainder 64
    根据上表, 把没个字符的value值 乘上 字符在字符串中的位置(1开始算)
把没个乘积加起来
因为CODESET B 104(这是规定, 不要问我为什么)
所以, 还要加上 104 
最后, 除以103, 所得的余数就是 校验码 的value, 然后在表中找到对应的字符
就可以了.
 
有心人应该注意到了, value>=95的时候, 是没有字符的(事实上还是有的, 
只不过是unicode字符)
好了, 原理就阐述到这里, 还有什么不懂的话, 大家看看代码好了.
至于用在水晶报表上的问题, 我这里是配合条码字体的, 我会上传一个我正在用的字体.
代码如下:
Public Function StringToCode128(ByVal input As String) As String
        Try
            Dim endchar As Char
            Dim total As Int64 = 104
            Dim tmp As Integer
            For i As Int16 = 1 To input.Length
                tmp = Asc(input.Substring(i - 1, 1))
                If tmp >= 32 Then
                    total += (tmp - 32) * i
                Else
                    total += (tmp + 64) * i
                End If
            Next
            Dim endAsc = total Mod 103
            If endAsc >= 95 Then
                Select Case endAsc
                    Case 95
                        endchar = "Ã"
                    Case 96
                        endchar = "Ä"
                    Case 97
                        endchar = "Å"
                    Case 98
                        endchar = "Æ"
                    Case 99
                        endchar = "Ç"
                    Case 100
                        endchar = "È"
                    Case 101
                        endchar = "É"
                    Case 102
                        endchar = "Ê"
                End Select
            Else
                endAsc += 32
                endchar = Chr(endAsc)
            End If
            Return "Ì" & input & endchar.ToString() & "Î"
        Catch ex As Exception
            WriteLog(ex.Message, ex.StackTrace)
            Return String.Empty
        Finally
        End Try
    End Function

我放大一下上面用到的特殊字符,大家看看清楚:
起始符:Ì
终止符:Î
value95:Ã
 
value96:Ä
 
value97:Å
 
value98:Æ
 
value99:Ç
 
value100:È
 
value101:É
 
value102:Ê
#endregion
根据以上代码,这作了几个转换的版本,用于不同的环境,
C#版本:

        private string  StringToCode128(string input)
        {
            try
            {
                char endChar=(char)0;
                Int64 total = 104;
                int tmp;
                Int64 endAsc;
                for (int i = 0; i < input.Length; i++)
                {
                    tmp = (int)(Convert.ToChar(input.Substring(i, 1)));
                    if (tmp >= 32)
                    {
                        total += (tmp - 32) * (i + 1);
                    }
                    else
                    {
                        total += (tmp + 64) * (i + 1);
                    }
                }
                endAsc = total % 103;
                if (endAsc >= 95)
                {
                    switch (endAsc)
                    {
                        case 95:
                            endChar = 'Ã';
                            break;
                        case 96:
                            endChar = 'Ä';
                            break;
                        case 97:
                            endChar = 'Å';
                            break;
                        case 98:
                            endChar = 'Æ';
                            break;
                        case 99:
                            endChar = 'Ç';
                            break;
                        case 100:
                            endChar = 'È';
                            break;
                        case 101:
                            endChar = 'É';
                            break;
                        case 102:
                            endChar = 'Ê';
                            break;
                    }
                }
                else
                {
                    endAsc += 32;
                    endChar = (char)endAsc;
                }
                return "Ì" + input + endChar.ToString() + "Î";

            }
            catch (Exception ex)
            {
                MessageBox.Show("Error");
                return string.Empty;
            }

      }

Office Excel版本:
Public Function Code128b(DataToEncode As String) As String
            Dim endchar As string

            Dim total As Integer 
            total = 104
            Dim tmp As Integer
            dim i as integer
            dim Ito as integer
            Ito = Len(dataToEncode)
            dim tempstring as string 
            dim j as integer
            
            For i = 1 To Ito
                 tempstring = Mid(DataToEncode, i, 1)
                tmp = AscW(tempstring)

                If tmp >= 32 Then
                    total =total+ (tmp - 32) * i
                Else
                    total =total+ (tmp + 64) * i
                End If
            Next
            dim endasc as integer

            endAsc = total Mod 103

            If endAsc >= 95 Then
                Select Case endAsc
                    Case 95
                        endchar = ChrW(195)
                    Case 96
                         endchar = ChrW(196)
                    Case 97
                         endchar = ChrW(197)
                    Case 98
                         endchar = ChrW(198)
                    Case 99
                         endchar = ChrW(199)
                    Case 100
                         endchar = ChrW(200)
                    Case 101
                        endchar = ChrW(201)
                    Case 102
                        endchar = ChrW(202)
                End Select
            Else
                endAsc =endasc + 32
                endchar = ChrW(endAsc)
            End If
           Code128a=ChrW(204) + DataToEncode + endchar + ChrW(206)
end function

OpenOffice版本(注:此版本只能在支持VBAOxygenOffice中应用):
Public Function Code128a(DataToEncode As String) As String
           Dim endchar As string

           Dim total As Integer 
           total = 104
           Dim tmp As Integer
           dim i as integer
           dim Ito as integer
          Ito = Len(DataToEncode)
          dim tempstring as string 
           dim j as integer
          
          For i = 1 To Ito
                tempstring = Mid(DataToEncode, i, 1)
               tmp = AscW(tempstring)
                If tmp >= 32 Then
                    total =total+ (tmp - 32) * i
                Else
                    total =total+ (tmp + 64) * i
                End If
            Next
            dim endasc as integer

            endAsc = total Mod 103

            If endAsc >= 95 Then
                Select Case endAsc
                    Case 95
                        endchar = "Ã"
                    Case 96
                        endchar = "Ä"
                    Case 97
                        endchar = "Å"
                    Case 98
                        endchar = "Æ"
                    Case 99
                        endchar = "Ç"
                    Case 100
                        endchar = "È"
                    Case 101
                        endchar = "É"
                    Case 102
                        endchar = "Ê"
                End Select
            Else
                endAsc =endasc + 32
                endchar = ChrW(endAsc)
            End If
           Code128a= "Ì" + DataToEncode + endchar + "Î"
end function
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值