第一种方式是使用 Reports Builder 实现对 128 码编码, 在 Metalink 305090.1[1] 有
比较详尽的描述,其中的 IDAUTOMATION.PLL 中包含方法 Code128A, Code128B
及 Code128C 分别实现了 A,B,C 类 128 码的编码。具体的实现方法请参照 MetaLink
305090.1 。
第二种方法是通过 XML Publisher 实现 128 码的编码。因为超过 128 的 ASCII 码对
应的特殊字符在 PL/SQL 中无法显示,但是在 128 码中使用这些字符作为 128 码的
起始终止位以及校验位,编码的过程放在 PL/SQL 端实现并生成 XML 数据结合模板
生成条码较难实现。改变思路,我们把编码过程放在 JAVA 类中,通过在结合模板
时调用生成 128 码就可以实现条码的生成和打印。在《Oracle XML Publisher
Administration and Developer's Guide》中 Advanced Barcode Font Formatting
Implementation 中提供了这种方法的实现。在 Metalink 782809.1[2]中提供 JAVA 版
128 码编码实现类(BarcodeUtil.java)的下载,以及测试使用相应的模板文件
(TestBarcodeUtil.rtf)
以下内容以字体IDAutomationC128M 为演示
一.WINDOWS本地字体配置
下载条形码字体,复制到系统字体文件夹里,自动安装
二,上传java到服务器
1.查看java里路径 例如:package oracle.apps.xdo.template.rtf.util.barcoder;
上传java文件BarcodeUtil.java到目录 $JAVA_TOP/oracle/apps/xdo/template/rtf/util/barcoder 没有新建
编译java文件
java文件如下
- /*
- Code extracted from
- Oracle?XML Publisher
- Core Components Guide
- Release 10.1.3.3
- Pages 8-60 to 8-64
- */
- package oracle.apps.xdo.template.rtf.util.barcoder;
- import java.util.Hashtable;
- import java.lang.reflect.Method;
- import oracle.apps.xdo.template.rtf.util.XDOBarcodeEncoder;
- import oracle.apps.xdo.common.log.Logger;
- // This class name will be used in the register vendor
- // field in the template.
- public class BarcodeUtil implements XDOBarcodeEncoder
- // The class implements the XDOBarcodeEncoder interface
- {
- // This is the barcode vendor id that is used in the
- // register vendor field and format-barcode fields
- public static final String BARCODE_VENDOR_ID = "XMLPBarVendor";
- // The hashtable is used to store references to
- // the encoding methods
- public static final Hashtable ENCODERS = new Hashtable(10);
- // The BarcodeUtil class needs to be instantiated
- public static final BarcodeUtil mUtility = new BarcodeUtil();
- // This is the main code that is executed in the class,
- // it is loading the methods for the encoding into the hashtable.
- // In this case we are loading the three code128 encoding
- // methods we have created.
- static {
- try {
- Class[] clazz = new Class[] { "".getClass() };
- ENCODERS.put("code128a",mUtility.getClass().getMethod("code128a", clazz));
- ENCODERS.put("code128b",mUtility.getClass().getMethod("code128b", clazz));
- ENCODERS.put("code128c",mUtility.getClass().getMethod("code128c", clazz));
- } catch (Exception e) {
- // This is using the XML Publisher logging class to push
- // errors to the XMLP log file.
- Logger.log(e,5);
- }
- }
- // The getVendorID method is called from the template layer
- // at runtime to ensure the correct encoding method are used
- public final String getVendorID()
- {
- return BARCODE_VENDOR_ID;
- }
- //The isSupported method is called to ensure that the
- // encoding method called from the template is actually
- // present in this class.
- // If not then XMLP will report this in the log.
- public final boolean isSupported(String s)
- {
- if(s != null)
- return ENCODERS.containsKey(s.trim().toLowerCase());
- else
- return false;
- }
- // The encode method is called to then call the appropriate
- // encoding method, in this example the code128a/b/c methods.
- public final String encode(String s, String s1)
- {
- if(s != null && s1 != null)
- {
- try
- {
- Method method = (Method)ENCODERS.get(s1.trim().toLowerCase());
- if(method != null)
- return (String)method.invoke(this, new Object[] { s });
- else
- return s;
- }
- catch(Exception exception)
- {
- Logger.log(exception,5);
- }
- return s;
- } else {
- return s;
- }
- }
- /** This is the complete method for Code128a */
- public static final String code128a( String DataToEncode )
- {
- char C128_Start = (char)203;
- char C128_Stop = (char)206;
- String Printable_string = "";
- char CurrentChar;
- int CurrentValue=0;
- int weightedTotal=0;
- int CheckDigitValue=0;
- char C128_CheckDigit='w';
- DataToEncode = DataToEncode.trim();
- weightedTotal = ((int)C128_Start) - 100;
- for( int i = 1; i <= DataToEncode.length(); i++ )
- {
- //get the value of each character
- CurrentChar = DataToEncode.charAt(i-1);
- if( ((int)CurrentChar) < 135 )
- CurrentValue = ((int)CurrentChar) - 32;
- if( ((int)CurrentChar) > 134 )
- CurrentValue = ((int)CurrentChar) - 100;
- CurrentValue = CurrentValue * i;
- weightedTotal = weightedTotal + CurrentValue;
- }
- //divide the WeightedTotal by 103 and get the remainder,
- //this is the CheckDigitValue
- CheckDigitValue = weightedTotal % 103;
- if( (CheckDigitValue < 95) && (CheckDigitValue > 0) )
- C128_CheckDigit = (char)(CheckDigitValue + 32);
- if( CheckDigitValue > 94 )
- C128_CheckDigit = (char)(CheckDigitValue + 100);
- if( CheckDigitValue == 0 ){
- C128_CheckDigit = (char)194;
- }
- Printable_string = C128_Start + DataToEncode + C128_CheckDigit + C128_Stop + " ";
- return Printable_string;
- }
- /** This is the complete method for Code128b ***/
- public static final String code128b( String DataToEncode )
- {
- char C128_Start = (char)204;
- char C128_Stop = (char)206;
- String Printable_string = "";
- char CurrentChar;
- int CurrentValue=0;
- int weightedTotal=0;
- int CheckDigitValue=0;
- char C128_CheckDigit='w';
- DataToEncode = DataToEncode.trim();
- weightedTotal = ((int)C128_Start) - 100;
- for( int i = 1; i <= DataToEncode.length(); i++ )
- {
- //get the value of each character
- CurrentChar = DataToEncode.charAt(i-1);
- if( ((int)CurrentChar) < 135 )
- CurrentValue = ((int)CurrentChar) - 32;
- if( ((int)CurrentChar) > 134 )
- CurrentValue = ((int)CurrentChar) - 100;
- CurrentValue = CurrentValue * i;
- weightedTotal = weightedTotal + CurrentValue;
- }
- //divide the WeightedTotal by 103 and get the remainder,
- //this is the CheckDigitValue
- CheckDigitValue = weightedTotal % 103;
- if( (CheckDigitValue < 95) && (CheckDigitValue > 0) )
- C128_CheckDigit = (char)(CheckDigitValue + 32);
- if( CheckDigitValue > 94 )
- C128_CheckDigit = (char)(CheckDigitValue + 100);
- if( CheckDigitValue == 0 ){
- C128_CheckDigit = (char)194;
- }
- Printable_string = C128_Start + DataToEncode + C128_CheckDigit + C128_Stop + " ";
- return Printable_string;
- }
- /** This is the complete method for Code128c **/
- public static final String code128c( String s )
- {
- char C128_Start = (char)205;
- char C128_Stop = (char)206;
- String Printable_string = "";
- String DataToPrint = "";
- String OnlyCorrectData = "";
- int i=1;
- int CurrentChar=0;
- int CurrentValue=0;
- int weightedTotal=0;
- int CheckDigitValue=0;
- char C128_CheckDigit='w';
- DataToPrint = "";
- s = s.trim();
- for(i = 1; i <= s.length(); i++ )
- {
- //Add only numbers to OnlyCorrectData string
- CurrentChar = (int)s.charAt(i-1);
- if((CurrentChar < 58) && (CurrentChar > 47))
- {
- OnlyCorrectData = OnlyCorrectData + (char)s.charAt(i-1);
- }
- }
- s = OnlyCorrectData;
- //Check for an even number of digits, add 0 if not even
- if( (s.length() % 2) == 1 )
- {
- s = "0" + s;
- }
- //<<<< Calculate Modulo 103 Check Digit and generate
- // DataToPrint >>>>//Set WeightedTotal to the Code 128 value of
- // the start character
- weightedTotal = ((int)C128_Start) - 100;
- int WeightValue = 1;
- for( i = 1; i <= s.length(); i += 2 )
- {
- //Get the value of each number pair (ex: 5 and 6 = 5*10+6 =56)
- //And assign the ASCII values to DataToPrint
- CurrentChar = ((((int)s.charAt(i-1))-48)*10) + (((int)s.charAt(i))-48);
- if((CurrentChar < 95) && (CurrentChar > 0))
- DataToPrint = DataToPrint + (char)(CurrentChar + 32);
- if( CurrentChar > 94 )
- DataToPrint = DataToPrint + (char)(CurrentChar + 100);
- if( CurrentChar == 0)
- DataToPrint = DataToPrint + (char)194;
- //multiply by the weighting character
- //add the values together to get the weighted total
- weightedTotal = weightedTotal + (CurrentChar * WeightValue);
- WeightValue = WeightValue + 1;
- }
- //divide the WeightedTotal by 103 and get the remainder,
- //this is the CheckDigitValue
- CheckDigitValue = weightedTotal % 103;
- if((CheckDigitValue < 95) && (CheckDigitValue > 0))
- C128_CheckDigit = (char)(CheckDigitValue + 32);
- if( CheckDigitValue > 94 )
- C128_CheckDigit = (char)(CheckDigitValue + 100);
- if( CheckDigitValue == 0 ){
- C128_CheckDigit = (char)194;
- }
- Printable_string = C128_Start + DataToPrint + C128_CheckDigit + C128_Stop + " ";
- Logger.log(Printable_string,5);
- return Printable_string;
- }
- } /*End BarcodeUtil class */
三,生成xml数据源
举例如下
- <?xml version="1.0" encoding="UTF-8"?>
- <RECEIPT_APPLIED>
- <LINES>
- <ITEM_CODE>F4990010010</ITEM_CODE>
- <ITEM_NAME><![CDATA[财税通软件 V1.0]]></ITEM_NAME>
- <BARCODE>912014266</BARCODE>
- </LINES>
- <LINES>
- <ITEM_CODE>F4990010010</ITEM_CODE>
- <ITEM_NAME><![CDATA[财税通软件 V1.0]]></ITEM_NAME>
- <BARCODE>912014265</BARCODE>
- </LINES>
- </RECEIPT_APPLIED>
四.根据数据源制作模板
说明:REG里面 <?register-barcode-vendor:'oracle.apps.xdo.template.rtf.util.barcoder.BarcodeUtil';'XMLPBarVendor'?> 注册条码编码类
条码里 <?format-barcode:BARCODE;'Code128a';'XMLPBarVendor'?> 数据格式化
五.注册数据源,模板
略
六.上传字体
在XML Publisher Administrator职责下,首先上传字体文件
七.配置字体映射
在XML Publisher Administrator职责下,定义字体转换映射集
由于我们的模板使用的是RTF格式的,因此Type需要选择FO To PDF
在XML Publisher Administrator职责下,定义字体转换映射关系
输入Font Family,这个值可以打开字体文件来查看
根据模板中使用字体的情况来选择Style和Weight
如果需要根据Locale来决定使用字体映射,则填入Language和Territory,不填代表所有语音环境下都适用
八,模板和字体映射关联
定义好字体映射之后,修改BIP模板文件的配置
查询出BIP模板定义后,点击右上角的 Edit Configuration 按钮
查找模板
展开FO Processing部分,设置Font mapping set为上面定义好的字体映射集
最后提交请求,查看输出