Оказывается существует шрифт ean13, позволяющий генерировать штрихкоды. Но напрямую его использовать нельзя, необходимо сместись символы по алгоритму, чтобы получить необходимое нам изображение.
Здесь я приведу рабочий код, с минимальным описанием. Функция преобразует уже готовые штрихкоды, с рассчитанными контрольными суммами (Как считать контрольную сумму, можно прочитать тамже). Код на Oracle PL/Sql.
Ean13 и UPC-A
Отличие штрихкода UPC-A от EAN13 в одном первом символе. В UPC-A он всегда = 0
CREATE OR REPLACE FUNCTION FNC_GET_BARCODE_EAN13 ( sFBarCode IN VARCHAR2)
RETURN VARCHAR2 IS retBarCode VARCHAR2(15);
lcnt INTEGER := 3;
tableA BOOLEAN := FALSE;
first CHAR(1);
sBarCode VARCHAR2(15);
BEGIN
sBarCode := sFBarCode;--внутренний буфер
IF(length(sBarCode) = 12) THEN
sBarCode := '0' || sBarCode;
ELSIF(length(sBarCode) <> 13) THEN
raise_application_error(-20010, 'Штрих код EAN13 должен содержать 13 символов');
return '';
END IF;
retBarCode := SUBSTR(sBarCode, 1, 1);
first := retBarCode;
retBarCode := retBarCode || chr(65+SUBSTR(sBarCode, 2, 1));
-- первая половина штрихкода
FOR lcnt IN 3..7 LOOP
tableA := FALSE;
if (lcnt=3) and ((first=0) or (first=1) or (first=2) or (first=3)) THEN tableA:=TRUE; END IF;
if (lcnt=4) and ((first=0) or (first=4) or (first=7) or (first=8)) THEN tableA:=TRUE; END IF;
if (lcnt=5) and ((first=0) or (first=1) or (first=4) or (first=5) or (first=9)) THEN tableA:=TRUE; END IF;
if (lcnt=6) and ((first=0) or (first=2) or (first=5) or (first=6) or (first=7)) THEN tableA:=TRUE; END IF;
if (lcnt=7) and ((first=0) or (first=3) or (first=6) or (first=8) or (first=9)) THEN tableA:=TRUE; END IF;
If tableA = TRUE THEN
retBarCode := retBarCode || chr(65+SUBSTR(sBarCode, lcnt, 1));
ELSE
retBarCode := retBarCode || Chr(75+SUBSTR(sBarCode, lcnt, 1));
END IF;
tableA := FALSE;
END LOOP;
--разделитель середины штрихкода
retBarCode := retBarCode || '*';
--вторая половина штрихкода
lcnt:=8;
FOR lcnt IN 8..13 LOOP
retBarCode := retBarCode || Chr(97+SUBSTR(sBarCode, lcnt, 1));
END LOOP;
--конец
retBarCode := retBarCode || '+';
RETURN retBarCode;
EXCEPTION
WHEN OTHERS THEN
RETURN '';
END;
EAN8
EAN8 имеет более простой механизм реализации, без смещений по таблице.
CREATE OR REPLACE FUNCTION FNC_GET_BARCODE_EAN8 ( sBarCode IN VARCHAR2)
RETURN VARCHAR2 IS retBarCode VARCHAR2(11);
lcnt INTEGER := 3;
BEGIN
if(length(sBarCode) <> 8) THEN
raise_application_error(-20010, 'Штрих код EAN8 должен содержать 8 символов');
return '';
END IF;
retBarCode := ':';
-- первая половина штрихкода
FOR lcnt IN 1..4 LOOP
retBarCode := retBarCode || chr(65+SUBSTR(sBarCode, lcnt, 1));
END LOOP;
--разделитель середины штрихкода
retBarCode := retBarCode || '*';
--вторая половина штрихкода
FOR lcnt IN 5..8 LOOP
retBarCode := retBarCode || Chr(97+SUBSTR(sBarCode, lcnt, 1));
END LOOP;
--конец
retBarCode := retBarCode || '+';
RETURN retBarCode;
EXCEPTION
WHEN OTHERS THEN
RETURN '';
END;
Объединение предыдущих двух функций (В зависимости от переданной строки)
CREATE OR REPLACE FUNCTION FNC_GET_BARCODE_EAN ( sBarCode IN VARCHAR2)
RETURN VARCHAR2 IS retBarCode VARCHAR2(15);
BEGIN
--Объединение EAN8 и EAN13
IF(length(sBarCode) = 8) THEN
retBarCode := FNC_GET_BARCODE_EAN8(sBarCode);
ELSE
retBarCode := FNC_GET_BARCODE_EAN13(sBarCode);
END IF;
RETURN retBarCode;
EXCEPTION
WHEN OTHERS THEN
RETURN '';
END;
Пример использования
select
FNC_GET_BARCODE_EAN('35967101') AS ean8,
FNC_GET_BARCODE_EAN('4607024381199') AS ean13,
FNC_GET_BARCODE_EAN('607024381199') AS upc
from DUAL;
Полученную строку (после работы функции FNC_GET_BARCODE_EAN) можно выводить шрифотом ean13 и получить работающий штрихкод.
Комментариев нет:
Отправить комментарий