2010-07-07 1 views
3

asp.net 응용 프로그램 (IKVM 사용)에서 iText와 함께 flyingsaucer를 사용하여 HTML을 PDF로 변환합니다. 스타일을 HTML에 직접 넣으면 잘 동작합니다 (심지어 스타일 태그 사이에 스타일을 넣을 수도 있습니다). 그러나 스타일 시트를 링크하면 스타일 시트가 발견되지 않고 스타일이없는 PDF가 만들어집니다.비행 접시가 스타일 시트를 읽지 않는다

이런 이유가 발생한 이유는 무엇입니까?

내가

 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를 링크하거나 삽입 할 때 CSS의 미디어 유형을 지정했는지 확인하십시오. "인쇄"또는 "모두"유형을 사용하십시오.

2

https를 사용하는 경우 비행 접시는 java의 키 저장소에 웹 서버 인증서가 포함될 때까지 .css 파일을 읽지 못합니다. 당신이 그것을 다른 방법으로 해결하는 경우

나도 같은 문제가 ...이 토론

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

를 참조 알려 주시기 바랍니다!

감사합니다.

+0

자바 기본 cacerts에 _also_를 추가하여 수정했습니다. (--server.ssl.key-store는 tomcat 전용입니다.) – lilalinux

1

쉬운 해결 방법 :

당신이 당신의 문서가 (당신의 응용 프로그램에 통합하기 위해 많은 코드를 작성하지 않고) 당신의 스타일로 작동하는지 빠른 테스트를 참조하십시오. 필요한 CSS를 복사하여 페이지에 붙여 넣기 만하면됩니다.

내 솔루션은 CSS를 읽고 전처리와 HTML에 넣어했다

더 많은-작업 솔루션. 이전 xhtml과 호환되지 않는 오래된 앱 이었기 때문에 JShp를 사용하여 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를 삽입하고 자바 스크립트를 지원하지 않습니다 비행 접시거야 때문에, 난 그냥 사전 처리의 끝 부분에 문서에서 이러한 참조를 제거합니다. 클래스 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 돔을 초기화하는 방법.글쎄, 난 렌더링 JSP 페이지의 내용을 읽고 내 PDF 생성 코드에 전달 요청 래퍼에 그렇게 : 당신은 당신의하는 setDocument 통화에서 문서의 기본 URL을 설정하지 않는

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

. Flying Saucer는 내가 발견 한대로 CSS와 이미지 링크를 해결해야합니다. 자세한 내용은 this answer을 참조하십시오.