2016-07-01 8 views
1

Я создаю файл PDF в проекте Java8 с использованием библиотеки Apache FOP. Английский контент отображается без каких-либо проблем, но русские символы странные. Они выглядят следующим образом: Ð # огР̧н.Apache FOP. Проблема с циририческими символами

Кажется, что проблема здесь как-то связана с кодировкой, но как я могу ее исправить?

здесь класс я использую для создания PDF:

public class PdfGenerationTools implements StreamResource.StreamSource 
    { 
    String content; 

    public PdfGenerationTools(String content) { 
     this.content = content; 
    } 

    @Override 
    public InputStream getStream() 
    { 
     ByteArrayInputStream foStream = 
       new ByteArrayInputStream(content.getBytes(StringTools.UTF8)); 

     // Basic FOP configuration. You could create this object 
     // just once and keep it. 
     FopFactory fopFactory = FopFactory.newInstance(); 
     fopFactory.setStrictValidation(false); // For an example 

     // Configuration for this PDF document - mainly metadata 
     FOUserAgent userAgent = getFOUserAgent(fopFactory); 

     // Transform to PDF 
     ByteArrayOutputStream fopOut = new ByteArrayOutputStream(); 
     try { 
      Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, 
        userAgent, fopOut); 
      TransformerFactory factory = 
        TransformerFactory.newInstance(); 
      Transformer transformer = factory.newTransformer(); 
      Source src = new 
        javax.xml.transform.stream.StreamSource(foStream); 
      Result res = new SAXResult(fop.getDefaultHandler()); 
      transformer.transform(src, res); 
      fopOut.close(); 
      return new ByteArrayInputStream(fopOut.toByteArray()); 

     } catch (Exception e) { 
      e.printStackTrace(); 
     } 

     return null; 
    } 

    private FOUserAgent getFOUserAgent(FopFactory factory) 
    { 
     FOUserAgent userAgent = factory.newFOUserAgent(); 

     userAgent.setProducer("Company"); 
     userAgent.setCreationDate(new Date()); 
     userAgent.setTitle("Printing jobs"); 
     userAgent.setTargetResolution(300); // DPI 

     return userAgent; 
    } 

    public static String initDoc() 
    { 
     return "<?xml version='1.0' encoding='ISO-8859-1'?>"+ 
       "<fo:root xmlns:fo='http://www.w3.org/1999/XSL/Format'>"+ 
       "<fo:layout-master-set>"+ 
       "<fo:simple-page-master master-name='A4' margin='2cm'>"+ 
       "<fo:region-body />"+ 
       "</fo:simple-page-master>"+ 
       "</fo:layout-master-set>"+ 
       "<fo:page-sequence master-reference='A4'>"+ 
       "<fo:flow flow-name='xsl-region-body'>"; 
    } 

    public static String closeDoc() 
    { 
     return "</fo:flow>"+ 
       "</fo:page-sequence>"+ 
       "</fo:root>"; 
    } 

    public static String initTable() 
    { 
     return "<fo:block space-before.optimum=\"10pt\"></fo:block>" + 
       "<fo:table table-layout=\"fixed\" border-width=\"1mm\" border-style=\"solid\">" + 
       "<fo:table-column column-number=\"1\" column-width=\"50%\"/>" + 
       "<fo:table-column column-number=\"2\" column-width=\"50%\"/>" + 
       "<fo:table-body>"; 
    } 

    public static String closeTable() 
    { 
     return "</fo:table-body>" + 
       "</fo:table>"; 
    } 

    public static String initTableRow() 
    { 
     return "<fo:table-row keep-together.within-page=\"always\">"; 
    } 

    public static String closeTableRow() 
    { 
     return "</fo:table-row>"; 
    } 

    public static String getCell(String ... args) 
    { 
     final StringBuilder sb = new StringBuilder(); 
     sb.append("<fo:table-cell padding=\"1mm\" border-width=\"1mm\" border-style=\"double\">"); 

     for (String arg : args) 
     { 
      sb.append("<fo:block font-family=\"SansSerif\">") 
        .append(arg) 
        .append("</fo:block>"); 
     } 

     sb.append("</fo:table-cell>"); 

     return sb.toString(); 
    } 
} 

Когда я изменил кодировку с 'ISO-8859-1' в 'UTF-8' мой кириллицы подстроку выглядит следующим образом: «## ###». Кажется, я отсутствующими шрифтами здесь ..

+1

Это похоже на многобайтовый UTF-8, который рассматривается как некоторая кодировка ISO/Windows по одному байту. Для остальных сделайте небольшой тест, например http://www.javaranch.com/journal/200409/CreatingMultipleLanguagePDFusingApacheFOP.html –

+1

Возможно, это проблема с настройкой шрифта ([этот мой ответ] (http://stackoverflow.com/) a/28251945/4453460) могут быть полезны) или проблема с кодировкой. Добавление небольшого фрагмента FO с кириллическими символами может помочь получить ответ, поскольку в противном случае невозможно попытаться воспроизвести вашу проблему (см. [MCVE] (http://stackoverflow.com/help/mcve)). – lfurini

+0

Я добавил фрагмент кода выше, чтобы показать, как я генерирую pdf-контент – user1053031

ответ

2

Вы должны использовать конфигурационный файл для ФОП, который указывает шрифты должны быть встроены в PDF-документе, например:

<?xml version="1.0" encoding="UTF-8"?> 
<fop version='1.0'> 
    <renderers> 
     <renderer mime='application/pdf'> 
      <fonts> 
       <!-- TTF fonts --> 
       <font kerning='yes' embed-url='c:\windows\fonts\arial.ttf'> 
        <font-triplet name='Arial' style='normal' weight='normal' /> 
       </font> 
       <font kerning='yes' embed-url='c:\windows\fonts\arialbd.ttf'> 
        <font-triplet name='Arial' style='normal' weight='bold' /> 
       </font> 
       <font kerning='yes' embed-url='c:\windows\fonts\ariali.ttf'> 
        <font-triplet name='Arial' style='italic' weight='normal' /> 
       </font> 
       <font kerning='yes' embed-url='c:\windows\fonts\arialbi.ttf'> 
        <font-triplet name='Arial' style='italic' weight='bold' /> 
       </font> 
       <font kerning='yes' embed-url='c:\windows\fonts\times.ttf'> 
        <font-triplet name='TimesNewRoman' style='normal' weight='normal' /> 
       </font> 
       <font kerning='yes' embed-url='c:\windows\fonts\timesbd.ttf'> 
        <font-triplet name='TimesNewRoman' style='normal' weight='bold' /> 
       </font> 
       <font kerning='yes' embed-url='c:\windows\fonts\timesi.ttf'> 
        <font-triplet name='TimesNewRoman' style='italic' weight='normal' /> 
       </font> 
       <font kerning='yes' embed-url='c:\windows\fonts\timesbi.ttf'> 
        <font-triplet name='TimesNewRoman' style='italic' weight='bold' /> 
       </font> 
       <font kerning='yes' embed-url='c:\windows\fonts\cour.ttf'> 
        <font-triplet name='CourierNew' style='normal' weight='normal' /> 
       </font> 
       <font kerning='yes' embed-url='c:\windows\fonts\courbd.ttf'> 
        <font-triplet name='CourierNew' style='normal' weight='bold' /> 
       </font> 
       <font kerning='yes' embed-url='c:\windows\fonts\couri.ttf'> 
        <font-triplet name='CourierNew' style='italic' weight='normal' /> 
       </font> 
       <font kerning='yes' embed-url='c:\windows\fonts\courbi.ttf'> 
        <font-triplet name='CourierNew' style='italic' weight='bold' /> 
       </font> 
       <font kerning='yes' embed-url='c:\windows\fonts\verdana.ttf'> 
        <font-triplet name='Verdana' style='normal' weight='normal' /> 
       </font> 
       <font kerning='yes' embed-url='c:\windows\fonts\verdanab.ttf'> 
        <font-triplet name='Verdana' style='normal' weight='bold' /> 
       </font> 
       <font kerning='yes' embed-url='c:\windows\fonts\verdanai.ttf'> 
        <font-triplet name='Verdana' style='italic' weight='normal' /> 
       </font> 
       <font kerning='yes' embed-url='c:\windows\fonts\verdanaz.ttf'> 
        <font-triplet name='Verdana' style='italic' weight='bold' /> 
       </font> 
      </fonts> 
     </renderer> 
    </renderers> 
</fop> 

Как использовать:

// configure fopFactory as desired 
FopFactory fopFactory = FopFactory.newInstance(); 
FOUserAgent foUserAgent = fopFactory.newFOUserAgent(); 
fopFactory.setUserConfig(new File("fop.xml")); 
+0

Наконец, я вернулся к этой проблеме .. Проблема в том, что я работаю под Ubuntu 14th. поэтому MS-шрифты здесь недоступны ( – user1053031

+2

Вы можете использовать любые шрифты, содержащие кириллические символы, а также вы можете установить шрифты MS в Ubuntu. Откройте Ubuntu Software Center и найдите «ttf-mscorefonts-installer». Это позволит установить основные шрифты Microsoft. –

Смежные вопросы