4

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"  />
4

4 に答える 4

3

よくある質問から:

PDF が CSS を取得していません。

PDF は「印刷」メディアとして扱われます。メディア タイプに関する CSS 2.1 仕様のセクションを参照してください。CSS をリンクまたは埋め込むときは、CSS のメディア タイプを指定していることを確認してください。タイプ「print」または「all」を使用します。

于 2010-07-23T10:56:59.860 に答える
2

https を使用している場合、java のキーストアに Web サーバーの証明書を含めるまで、空飛ぶ円盤は .css ファイルの読み取りに失敗します。

私も同じ問題を抱えています...このディスカッションを参照してください

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

他の方法で解決した場合は、お知らせください!!!

ありがとう。

于 2010-09-29T14:51:23.490 に答える
1

簡単な解決策:

ドキュメントが自分のスタイルで機能するかどうかを確認するための簡単なテストが必要な場合(アプリに統合するための多くのコードを記述せずに)。必要なCSSをコピーしてページに貼り付けるだけです。

より多くの作業ソリューション

私の解決策は、CSSを読み取り、プリプロセッサを使用してhtmlに配置することでした。xhtmlに完全に準拠していない可能性のある古いアプリだったので、JSoupを使用してhtmlをロードしました。以下のコードは前処理を行います。これらは、開始するためのコードスニペットであると言えます。素晴らしいことは、それが機能するようになったら、余分なコードなしでサーバー上の任意のページをPDFに変換できることです。私の状況では、特定のパラメーターを探すためにフィルターを設定します。そのパラメーターが存在する場合は、リクエストラッパーでリクエストをラップして、htmlページの最終的にレンダリングされたバイトにアクセスできるようにします。次に、Jsoupを使用して解析し、pre=processします。

/**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;
     }

次の質問は、JSOUPDomを初期化する方法です。レンダリングされた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);
 ...
于 2012-06-12T13:48:55.530 に答える