2014-02-06 8 views
1

Как создать ключи словаря информации о документе, содержащие символы юникода (обычно шведские символы, например C3A4 U + 00E4 ä). Я хотел бы использовать PdfStamper для ввода моих собственных метаданных в словаре информации о документе, но я не могу заставить его принять шведских символов.Юникодовые символы в словарных словах справочника по справочным документам

Ввод пользовательских метаданных с использованием Acrobat прекрасно работает и просматривает PDF-файл в текстовом редакторе. Я вижу, что символы кодируются как, например, # C3 # A4 для упомянутого выше символа. Так есть ли способ достичь этого программным путем с помощью iText PdfStamper ???

С уважением Маттиас

PS. Нет никакой проблемы с символами Юникода в значениях словаря информации, но ключи - другая история.

ответ

0

Пожалуйста, взгляните на пример NameObject и дайте ему попробовать. Вы увидите, что iText автоматически ускользает от специальных символов в именах.

IText следует спецификации ISO-32000-1, что статистика (7.3.5, имя объекты):

Начиная с PDF 1.2 объект имени атомного символ однозначно определяются последовательностью любых символов (8-битные значения), кроме нуля (код символа 0). Однозначно определено, что любые два объекта имен , составленные из одной и той же последовательности символов, обозначают один и тот же объект. Атомный означает, что имя не имеет внутренней структуры; хотя это , определяемый последовательностью символов, эти символы не являются считаются элементами имени.

не часть имени, но приставка, указывающая на то, что следует, является последовательность символов, представляющих имя в файле PDF и должны следовать этим правилам:

а) символ (23H) (#) в имени записывается с использованием его двухзначного шестнадцатеричного кода (23) , которому предшествует NUMBER SIGN.

б) Любой символ в имени, которое является регулярным характером (кроме NUMBER знака) должно быть записано, как таковые, либо с помощью его 2-значного кода шестнадцатеричных, которому предшествует знак номера.

c) Любой символ, который не является регулярным символом, должен быть записан с использованием его двузначного шестнадцатеричного кода, которому предшествует только NUMBER SIGN.

ПРИМЕЧАНИЕ 1. В файл PDF нет уникальной кодировки имен, поскольку обычные символы могут быть закодированы одним из двух способов.

Белого пространство используется как часть имени должно всегда быть закодировано с использованием 2-значного шестнадцатеричного представления и ни белого пространство не может вмешиваться между солидусом и кодированным именем.

Обычных символы, которые находятся за пределами диапазона восклицательного знака (21h) (!) До тильды (7Eh) (~) должны быть написаны с использованием шестнадцатеричной обозначения.

Токен SOLIDUS (косая черта, за которой не следует никаких обычных символов) вводит уникальное действительное имя, определяемое пустой последовательностью символов .

ПРИМЕЧАНИЕ 2 Примеры, показанные в таблице 4 и содержащие #, недействительны буквальные имена в PDF 1.0 или 1.1.

Я не скопирую/вставляю таблицу 4, но я не вижу никакого примера, который использует символы, состоящие из двух байтов. Можете ли вы поделиться PDF-файлом, который содержит имя с двухбайтным символом, который ведет себя так, как вы хотите? В спецификации PDF явно указано, что символы в контексте имен - это 8-битные значения. Вы, кажется, говорить о 16-битных значений ...

Дополнительное примечание: в текущей реализации IText, мы только смотрим на 8 бит:

c = (char)(chars[k] & 0xff); 

Мы сознательно отбрасывать все выше бит, когда передаются символы с более чем 8 битами.

На самом деле, я думаю, что я ответил на ваш вопрос. Первоначально, я думал, вы просили добавить этот персонаж: http://www.fileformat.info/info/unicode/char/c3a4/index.htm

Как оказалось, вам нужно всего лишь "\u00e4" (ä). Я сделал небольшой пример кода, который демонстрирует, как добавить пользовательскую запись в DID, содержащий этот символ: ChangeInfoDictionary.

public void manipulatePdf(String src, String dest) throws IOException, DocumentException { 
    PdfReader reader = new PdfReader(src); 
    PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest)); 
    Map<String, String> info = reader.getInfo(); 
    info.put("Special Character: \u00e4", "\u00e4"); 
    stamper.setMoreInfo(info); 
    stamper.close(); 
    reader.close(); 
} 

Конечно, при открытии PDF в программе просмотра PDF, вам не обязательно видеть «особый характер: а» как ключевое значение, но это проблема просмотра PDF. При открытии PDF в текстовом редакторе, вы ясно видите:

/Special#20Character:#20#e4(ä) 

Это означает, что IText правильно избежал особого характера.

Однако: как вы отметили в своем комментарии, персонаж не отображается в Adobe Reader. На основе PDF я создал с помощью Acrobat, я нашел обходной путь, используя следующий код:

StringBuffer buf = new StringBuffer(); 
buf.append((char) 0xc3); 
buf.append((char) 0xa4); 
info.put(buf.toString(), "\u00e4"); 

Теперь персонаж показан правильно. Другими словами: речь идет о кодировании ...

+0

Я обновил свой ответ. В дополнительном фрагменте вы найдете обходное решение. –

0

Просто хотел поделиться небольшим экспериментом на C#, иллюстрирующим один довольно легкий способ получить специальные символы в словарных словарях словаря.

 string inputString = "My key with åäö"; 
     byte[] inputBytes = Encoding.UTF8.GetBytes(inputString); 
     string convertedString = Encoding.UTF7.GetString(inputBytes); 
     info.Add(convertedString, "My value with åäö"); 

(информация является словарь используется для добавления метаданных) Затем просто использовать PdfStamper, чтобы получить информацию в формате PDF. Метаданные хранятся правильно в PDF и могут быть интерпретированы Adobe Reader.