2010-07-07 2 views
3

Я использую flyingsaucer вместе с iText в приложении asp.net (используя IKVM) для преобразования HTML в PDF. Если я помещаю стиль непосредственно в html, он отлично работает (даже стили помещаются между тегами стиля), но когда я связываю таблицу стилей, она не замечает этого и создает PDF без стилей.Flying Saucer не читает таблицу стилей

Любая причина, по которой это происходит?

Это код, который я использую

 Dim renderer As New ITextRenderer 
     Dim buf As New StringBuffer 
     buf.append(HTML) 
     Dim builder As DocumentBuilder = DocumentBuilderFactory.newInstance.newDocumentBuilder() 
     Dim doc As Document = builder.parse(New StringBufferInputStream(buf.toString)) 

     renderer.setDocument(doc, Nothing) 
     renderer.layout() 

     renderer.createPDF(os) 

И это ссылка на таблицу стилей

<link rel="stylesheet" href="stylemove.css" type="text/css" /> 

ответ

3

from the FAQ:

Мой PDF не собирание мой CSS!

PDF рассматривается как «печатный» носитель; см. CSS 2.1 specification section on media types. Убедитесь, что вы указали тип носителя для своего CSS, когда вы его связываете или вставляете; использовать тип «печать» или «все».

2

Если вы используете https, то летающая тарелка не сможет прочитать файлы .css, пока вы не создадите хранилище java, включая сертификат вашего веб-сервера.

У меня такая же проблема тоже ... см это обсуждение

https://code.google.com/p/jmesa/issues/detail?id=182

Если вы решили по-другому, пожалуйста, дайте мне знать !!!

Спасибо.

+0

Добавив его _also_ в java default, cacerts исправил его. (-server.ssl.key-store предназначен только для tomcat) – lilalinux

1

простое решение:

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

Чем больше-работа Решение

Мое решение было читать CSS и поместить его в HTML с препроцессором. Поскольку это было более старое приложение, которое может быть не полностью совместимо с xhtml, я использовал JSoup для загрузки html. Следующий код выполняет предварительную обработку. Я скажу, что это фрагменты кода, чтобы вы начали. Самое замечательное, как только вы его заработаете, вы можете преобразовать любую страницу на своем сервере в PDF без дополнительного кода. В моей ситуации я настраиваю фильтр для поиска определенного параметра. Если этот параметр присутствует, я обернуваю запрос с помощью обертки запроса, чтобы получить доступ к окончательным визуализированным байтам страницы html. Затем я использую Jsoup для его анализа, а затем pre = обрабатывает его.

/**this method uses JSOUP Document here is org.jsoup.nodes.Document 
*/ 
@Override 
    public void modifyDOM(MyResourceResolver resources, Document normalizedDOM) { 

     //move style into head section 
     Elements styleTags = normalizedDOM.getElementsByTag("style"); 

     normalizedDOM.select("style").remove(); 

     for (org.jsoup.nodes.Element linkElement : styleTags) { 

      String curHead = normalizedDOM.head().html(); 
      normalizedDOM.head().html(curHead + "\n" + linkElement.html() + "\n"); 


     } 


     //now resolve css 
     Elements links = normalizedDOM.getElementsByTag("link"); 


     for (org.jsoup.nodes.Element linkElement : links) { 

      String linkHref = linkElement.attr("href"); 
      if (linkHref == null) { 
       linkHref = ""; 
      } 


      String mediaSelector = linkElement.attr("media"); 
      if (mediaSelector == null) { 
       mediaSelector = ""; 
      } 
      mediaSelector = mediaSelector.trim(); 
      if ("".equalsIgnoreCase(mediaSelector) || ("print".equalsIgnoreCase(mediaSelector))) { 

       byte[] contents = resources.getContentsOfHref(linkHref); 

       if (null != contents) { 
        //we've got the info let's add to the document as is 
        Tag styleTag = Tag.valueOf("style"); 
        Attributes styleAttributes = new Attributes(); 
        styleAttributes.put("type", "text/css"); 
        String baseUri = ""; 
        org.jsoup.nodes.Element styleElement = new Element(styleTag, baseUri, styleAttributes); 
        styleElement.text(new String(contents)); 
        String curHead = normalizedDOM.head().html(); 
        normalizedDOM.head().html(curHead + "\n<style type='text/css'>" + styleElement.html() + "</style>\n"); 

       } 
      } 


     } 


     normalizedDOM.select("link").remove(); 
     normalizedDOM.select("script").remove(); 
    } 

Поскольку я вставив CSS и летающей тарелки не поддерживает JavaScript, я просто удалить эти ссылки из документа в конце предварительной обработки. класс MyResourceResolver - это всего лишь класс, который я написал, который имеет ссылку на контекст сервлета. метод, который на самом деле читает байты в CSS с сервера выглядит следующим образом:

public byte[] getContentsOfHref(String href) { 
     byte[] retval = null; 
     byte[] buf = new byte[8195]; 
     int nread; 
     ByteArrayOutputStream bos = new ByteArrayOutputStream(); 

     InputStream is = null; 
     try { 

      if (href.startsWith("/myurlcontext")) { 
       href = href.substring("/myurlcontext".length()); 
      } 
       is = context.getResourceAsStream(href); 
       while ((nread = is.read(buf)) >= 0) { 
        bos.write(buf, 0, nread); 
       } 
       retval = bos.toByteArray(); 


     } catch (Exception ex) { 
      //do nothing for now 
     } finally { 
      try { 
       is.close(); 
      } catch (Exception ex) {/*do nothing*/} 
     } 
     if (retval == null) { 
      System.out.println("Did not find: " + href); 
     } else { 
      System.out.println("Found: " + href + " " + retval.length + " bytes"); 
     } 
     return retval; 
    } 

Следующий вопрос, как инициализировать JSOUP Dom.Ну, я делаю это в запросе обертку, которая считывает содержимое оказанной страницы JSP и передает его в мой PDF код генерирующего:

String renderedJSPString = new String(renderedJSP); 
//these escape sequences are nuisance in xhtml. 
     renderedJSPString = renderedJSPString.replaceAll("&nbsp;|&copy;|&amp;|&lt;|&gt;", ""); 
     org.jsoup.nodes.Document parsedHtmlDOM = Jsoup.parse(renderedJSPString); 
     org.jsoup.nodes.Document normalizedDOM = parsedHtmlDOM.normalise(); 
     normalizedDOM.outputSettings().escapeMode(Entities.EscapeMode.xhtml); 
     normalizedDOM.outputSettings().prettyPrint(true); 
... 
preProcessor.modifyDOM(resolver, normalizedDOM); 
... 
0

Вы не установки базового URL вашего документа в вашем setDocument вызова. Flying Saucer нуждается в том, чтобы разрешить ссылки на CSS и изображения, как я обнаружил. Для получения дополнительной информации см. this answer.

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