Oracle  提供两种方式实现 128 码的编码
第一种方式是使用 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本地字体配置

下载条形码字体,拷贝到系统字体目录里,自己主动安装

EBS条形码打印


二,上传java到server

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数据源

举比例如以下



四.依据数据源制作模板

EBS条形码打印

说明:REG里面   <?register-barcode-vendor:'oracle.apps.xdo.template.rtf.util.barcoder.BarcodeUtil';'XMLPBarVendor'?> 注冊条码编码类

           条码里        <?format-barcode:BARCODE;'Code128a';'XMLPBarVendor'?>    数据格式化


五.注冊数据源,模板


六.上传字体

在XML Publisher Administrator职责下,首先上传字体文件

EBS条形码打印


七.配置字体映射

在XML Publisher Administrator职责下,定义字体转换映射集

因为我们的模板使用的是RTF格式的。因此Type须要选择FO To PDF


EBS条形码打印

在XML Publisher Administrator职责下,定义字体转换映射关系

输入Font Family,这个值能够打开字体文件来查看

依据模板中使用字体的情况来选择Style和Weight

假设须要依据Locale来决定使用字体映射,则填入Language和Territory,不填代表全部语音环境下都适用


EBS条形码打印


EBS条形码打印


八,模板和字体映射关联

定义好字体映射之后,改动BIP模板文件的配置

查询出BIP模板定义后,点击右上角的 Edit Configuration button


查找模板

EBS条形码打印

展开FO Processing部分,设置Font mapping set为上面定义好的字体映射集

EBS条形码打印


最后提交请求,查看输出

EBS条形码打印


附1:metalink

In this Document

Purpose
  Scope
  Details
  Overview
  Limitation
  Steps to Implement
  EnterpriseOne 8.98.3.0 and later (including 9.1):
  EnterpriseOne 8.98.2.4 and older:
  References

APPLIES TO:

JD Edwards EnterpriseOne Tools - Version 8.97 and later
BI Publisher (formerly XML Publisher) - Version 11.1.1.5.0 to 11.1.1.5.0 [Release 11.1]
Information in this document applies to any platform.

PURPOSE

Information Center: BI Publisher in the JD Edwards EnterpriseOne Tools and Technology Product > Information Center: Using BI Publisher in the JD Edwards EnterpriseOne Tools and Technology Product > Note 1460779.2

This document outlines the steps to use barcode java handlers to add control characters to barcode content in reports produced by embedded BI Publisher for EnterpriseOne.

SCOPE

Embedded BI Publisher for EnterpriseOne.

DETAILS

Overview

Barcodes are a representation of a string of data in a barcode font. In order to be readable by barcode scanners, data represented in barcode format need to be preceded and followed by their respective control characters. See external page http://en.wikipedia.org/wiki/Code_128 for more information. 

This can be archived in BI Publisher by invoking a java handler within the RTF template. The process works in two steps. First the BI Publisher engine merges the XML data with the template when submitting the report definition. Second the RTF template itself invokes the barcode java handler at runtime to add the control characters to the barcode string.

Limitation

Barcode encoding will not work if using a PDF type template with Embedded BI Publisher for EnterpriseOne. This is because there is no way to add the necessary call to the java script to enable the start and stop control characters in PDF templates and this can only be done in RTF templates. Without the java script, the font will show in the final output, however it will be unreadable to the barcode scanners.

Steps to Implement

EnterpriseOne 8.98.3.0 and later (including 9.1):

Since tools release 8.98.3.0 we include a newer BI Publisher core engine (10.1.3.4.1) which has built in support for barcode 128a,b,c. The barcode function can be invoked directly using te following command in your RTF template:

<?format-barcode:FieldName;'code128b'?>

Where FieldName is the name of the dynamic field you want to convert to Barcode 128b.

You can use encodings 128a and 128c as well, for example:

<?format-barcode:FieldName;'code128a'?>
<?

format-barcode:FieldName;'code128c'?>

https://blogs.oracle.com/xmlpublisher/entry/bundled_barcodes_batman_1 for more details.

EnterpriseOne 8.98.2.4 and older:

The following steps layout all pieces necessary to embed readable barcode strings in reports produced by BI Publisher for EnterpriseOne 8.98.2.4 and older.

The implementation of this solution requires knowledge of BI Publisher for EnterpriseOne and java programming language.

 

  1.  Obtain a java handler from the barcode vendor

    A sample of a barcode handler code is provided in the Oracle XML Publisher - Core Components Guide - Release 10.1.3.3 - Pages 8-60 to 8-64 (Document 704542.1) and included in the attachment BarcodeUtil.java

    This source file is provided only as a reference. The actual code should be provided by the barcode font vendor. Oracle does not support the creation or customization of the barcode java handler.

      
  2. The java handler must contain three methods to be called by BI Publisher engine:

    getVendorID();
    isSupported(String type);
    encode(String data, String type);
     
  3. Take note of the package location specified in the java source (usually the first line)

    Example: package oracle.apps.xdo.template.rtf.util.barcoder;
     
  4. Check the Java Runtime Environment (JRE) in use on the enterprise server where E1 XML PUBLISHER kernel runs. Login as the user who starts E1 services and issue command java -version from a command console.

    Note about AS/400: the Enterprise Server Minimum Technical Requirements referenced in document 747323.1 contains information about the necessary Java Developer Kit installed on this server platform.
     
  5. Copy xdocore.jar file from EnterpriseOne enterprise server located in '..\system\classes' folder to a development workstation. Extract it using a tool such WinZip. Example: c:\temp
     
  6. Compile BarcodeUtil.java using the same JRE version used on the enterprise server. So for instance, if in step 4 you found java version 1.4.2_05, use JDK 1.4.2 update 5 or greater to compile the java class.

    Problems might appear if the class is compiled using a major Java release different than the one on the Enterprise Server (the machine that will execute the java compiled code at runtime).

    Example: if you are compiling it on Windows development workstation where c:\temp contains the java source file, the JDK and xdocore.jar, you can use the following commands:

    set path=c:\temp\jdk_1.4.2_18\bin
    set classpath=c:\temp\xdocore.jar
    javac -g BarcodeUtil.java


    If there are no major problems with the code, this will create a file name BarcodeUtil.class inside c:\temp

    Note: In situations where a version of the JDK used on the server is not available on the Windows platform, follow the procedures in steps 5 and 6 on the enterprise server itself. This is usually the case with AIX and iSeries servers which use IBM J9 JDK.

    This information is provided only as a reference. Problems setting java compiler environment and with the compilation of the barcode java handler provided by 3rd party vendors are not supported by Oracle. Please refer to the respective vendor for further assistance.

     
  7. Copy the new BarcodeUtil.class to the uncompressed structure of xdocore.jar you extracted in step 5. Place it in the same location given by the 'package' directive specified in the java source and found in step 3. 

    Example: if the java source contains:

    package oracle.apps.xdo.template.rtf.util.barcoder;

    place BarcodeUtil.class in folder name 'oracle\apps\xdo\template\rtf\util\barcoder' inside the extracted xdocore.
     
  8. Compress all class files (which must include the new BarcodeUtil.class you added in step 7) into a jar file and name it xdocore.jar. You can use WinZip to create xdocore.zip and then rename it to xdocore.jar.

    Make sure you only compress the original folder structure, not any additional upper folder level. Check this by opening the original xdocore.jarand the new xdocore.jar files with a zip utility and comparing the folder structure.
     
  9. Stop EnterpriseOne services on the enterprise server and backup the original xdocore.jar inside ...\system\classes. Place the backup in a folder outside the system PATH and CLASSPATH folders otherwise the system might still use the old .jar file.
     
  10. Copy xdocore.jar file created in step 8 to the enterprise server placing it in ...\system\classes
     
  11. Take this opportunity to check you can find the jas and jasroot log files produced by EnterpriseOne JVM based kernels - See Document 651589.1section 'jas/jasroot/jasdebug'. The location where these logs are saved is configured in file jdelog.properties found in   ...\system\classes (on AS/400 it is in ...\system). Edit it and check if the parameter FILE points to the same folder where other E1 kernel logs are saved.

    These logs are helpful when troubleshooting BI Publisher issues.
     
  12. Review the document 652457.1 to learn how to configure the barcode font in xdo.cfg file. Then configure the server xdo.cfg and copy the barcode truetype font to the enterprise server.
     
  13. Start EnterpriseOne services on the enterprise server.
     
  14. Install the font on the development workstation. This should be the same font you uploaded to the enterprise server in step 12. All it usually takes is to copy the truetype font to the 'fonts' folder inside C:\WINDOWS.
     
  15. Create a new template containing the following:
     
    • Directive to register the barcode handler (note the java path must match the location of the class file in xdocore.jar as explained in item 7):

      For example:

      <?register-barcode-vendor:'oracle.apps.xdo.template.rtf.util.barcoder.BarcodeUtil';'XMLPBarVendor'?>
    • Invoke the handler using the 'format-barcode' directive:

      For example:

      <?format-barcode:xml_field_name;'code128b';'XMLPBarVendor'?>

      See section titled Register the Barcode Encoding Class in the Oracle XML Publisher Core Components guide page 2-118 and 2-119 for more information see document 704542.1

      See attached file TestBarcodeUtil.rtf for a sample template.
       
  16. On the template, change the font of the data field to be encoded to be displayed using the barcode font you installed in step 14.
     
  17. Create a BI Publisher object using program P95600, upload the template you created in step 15, then create a report definition and associate it to the BI Publisher object. Submit it to the server and check the status of the output; it should be 'D' for done. If you get a status 'FX' this means that an error occurred when merging data and template. If that happened, check the jas log you setup in step 11 and look for errors. Normally java exceptions in the log will tell where the error occurred. 
     
  18. To verify that the java handler class is being called correctly, change the font on the data field to a humanly readable font, say Arial and run the report definition again. In the final output you should see the encoded value of the data formatted by the barcode handler. 

    If the output is the same as the data in the XML field then the BarcodeUtil handler is not being called correctly.


Below is a screenshot showing the output obtained using the steps above on EnterpriseOne 9.0 with tools release 8.98.2.4:

EBS条形码打印

Note 1:
The same result can be achieved with BI Publisher Desktop (MS Word Plug-in), using its own xdocore.jar and its fonts. These are usually located in"c:\Program Files\Oracle\BI Publisher\BI Publisher Desktop\Template Builder for Word", in the jlib and fonts subfolders.

If the issue is duplicated with the Desktop Plugin, then it is not an EnterpriseOne integration problem, and the cause should be sought either in the encryptor class from the barcode provider, or in the way it was integrated in the BarcodeUtil.java.

 

Note 2: 
There are many different types of barcodes. This document is specific to handling of 128a, 128b and 128c types. 

It is possible to integrate other dynamic barcode types to use with BI Publisher for EnterpriseOne, however these are considered to be out of the scope of EnterpriseOne support. 

If you have questions about using 2D barcode fonts you may like to consider the following links: 

https://blogs.oracle.com/xmlpublisher/entry/bundled_barcodes_batman_1 
https://blogs.oracle.com/xmlpublisher/entry/2d_barcodes_cracked
https://blogs.oracle.com/xmlpublisher/entry/2d_barcode_addendum
http://www.idautomation.com/oracle/xml_publisher_barcode.html.

Discussion and tips on how to incorporate QR barcodes:
https://blogs.oracle.com/xmlpublisher/entry/quick_quips_on_qr_codes

Enhancement bugs requesting enhanced support for barcodes:
BUG 11047749 - SUPPORT 2D BARCODE PRINTING

 

REFERENCES

NOTE:652457.1 - E1: XMLP: Adding a Font to be Used with Embedded Publisher for EnterpriseOne
NOTE:747323.1 - JD Edwards EnterpriseOne Current MTR Index
NOTE:651589.1 - E1: XMLP: How to Capture BI Publisher Logs
NOTE:789074.1 - E1: XMLP: BI Publisher for JD Edwards EnterpriseOne
NOTE:704542.1 - JD Edwards EnterpriseOne Tools 8.97 Implementation of Oracle Business Intelligence (BI) Publisher (Formerly XML Publisher)
BUG:11047749 - SUPPORT 2D BARCODE PRINTING - SAR: 8967722
 
 
 
 
 
 
 
  BULLETIN
  PUBLISHED
  2014-4-10
  2014-6-11
     

相关文章:

  • 2021-09-17
  • 2021-09-19
  • 2021-08-22
  • 2022-01-28
  • 2021-12-30
  • 2022-02-12
  • 2021-11-20
  • 2021-09-20
猜你喜欢
  • 2021-11-24
  • 2022-12-23
  • 2021-12-16
  • 2022-12-23
  • 2021-09-04
相关资源
相似解决方案