web-dev-qa-db-ja.com

JavaでXMLからPDFをどのように作成しますか?

現時点では、Java=でXMLファイルを作成し、XSL/XSLTで変換してJSPページに表示しています。次に、そのXMLファイルを取得して同じ情報を表示する必要があります。 PDFで。ある種のXSLファイルを使用してこれを行う方法はありますか?

iText Java-PDFライブラリを見たことがありますが、XMLとスタイルシートでそれを使用する方法が見つかりません。

どんな援助も大歓迎です。前もって感謝します!

25
Philip Morton

XSL Formattingオブジェクトを使用できます。これを行う方法に関するいくつかの優れた記事を以下に示します。

16
Bogdan Maxim

A-説明

Apache FOPフレームワークを使用してpdf出力を生成する必要があります。データをxml形式で提供し、ページをxsl-foファイルでレンダリングし、marginこのxsl-foファイルのページレイアウト

簡単なデモを提供します。mavenビルドツールを使用して、必要なjarファイルを収集します。ページの最後に、pdfに埋め込まれたsvgグラフィックがあることを通知してください。また、pdf内にsvgグラフィックを埋め込むことができることを示したいと思います。

B-サンプルXML入力データ

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="application/xml"?>
<users-data>
    <header-section>
        <data-type id="019">User Bill Data</data-type>
        <process-date>Thursday December 9 2016 00:04:29</process-date>
    </header-section>
    <user-bill-data>
        <full-name>John Doe</full-name>
        <postal-code>34239</postal-code>
        <national-id>123AD329248</national-id>
        <price>17.84</price>
    </user-bill-data>
    <user-bill-data>
        <full-name>Michael Doe</full-name>
        <postal-code>54823</postal-code>
        <national-id>942KFDSCW322</national-id>
        <price>34.50</price>
    </user-bill-data>
    <user-bill-data>
        <full-name>Jane Brown</full-name>
        <postal-code>66742</postal-code>
        <national-id>ABDD324KKD8</national-id>
        <price>69.36</price>
    </user-bill-data>
</users-data>

C-XSL-FOテンプレート

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" version="1.0">
    <xsl:output encoding="UTF-8" indent="yes" method="xml" standalone="no" omit-xml-declaration="no"/>
    <xsl:template match="users-data">
        <fo:root language="EN">
            <fo:layout-master-set>
                <fo:simple-page-master master-name="A4-portrail" page-height="297mm" page-width="210mm" margin-top="5mm" margin-bottom="5mm" margin-left="5mm" margin-right="5mm">
                    <fo:region-body margin-top="25mm" margin-bottom="20mm"/>
                    <fo:region-before region-name="xsl-region-before" extent="25mm" display-align="before" precedence="true"/>
                </fo:simple-page-master>
            </fo:layout-master-set>
            <fo:page-sequence master-reference="A4-portrail">
                <fo:static-content flow-name="xsl-region-before">
                    <fo:table table-layout="fixed" width="100%" font-size="10pt" border-color="black" border-width="0.4mm" border-style="solid">
                        <fo:table-column column-width="proportional-column-width(20)"/>
                        <fo:table-column column-width="proportional-column-width(45)"/>
                        <fo:table-column column-width="proportional-column-width(20)"/>
                        <fo:table-body>
                            <fo:table-row>
                                <fo:table-cell text-align="left" display-align="center" padding-left="2mm">
                                    <fo:block>
                                        Bill Id:<xsl:value-of select="header-section/data-type/@id"/>
                                        , Date: <xsl:value-of select="header-section/process-date"/>
                                    </fo:block>
                                </fo:table-cell>
                                <fo:table-cell text-align="center" display-align="center">
                                    <fo:block font-size="150%">
                                        <fo:basic-link external-destination="http://www.example.com">XXX COMPANY</fo:basic-link>
                                    </fo:block>
                                    <fo:block space-before="3mm"/>
                                </fo:table-cell>
                                <fo:table-cell text-align="right" display-align="center" padding-right="2mm">
                                    <fo:block>
                                        <xsl:value-of select="data-type"/>
                                    </fo:block>
                                    <fo:block display-align="before" space-before="6mm">Page <fo:page-number/> of <fo:page-number-citation ref-id="end-of-document"/>
                                    </fo:block>
                                </fo:table-cell>
                            </fo:table-row>
                        </fo:table-body>
                    </fo:table>
                </fo:static-content>
                <fo:flow flow-name="xsl-region-body" border-collapse="collapse" reference-orientation="0">
                    <fo:block>MONTHLY BILL REPORT</fo:block>
                    <fo:table table-layout="fixed" width="100%" font-size="10pt" border-color="black" border-width="0.35mm" border-style="solid" text-align="center" display-align="center" space-after="5mm">
                        <fo:table-column column-width="proportional-column-width(20)"/>
                        <fo:table-column column-width="proportional-column-width(30)"/>
                        <fo:table-column column-width="proportional-column-width(25)"/>
                        <fo:table-column column-width="proportional-column-width(50)"/>
                        <fo:table-body font-size="95%">
                            <fo:table-row height="8mm">
                                <fo:table-cell>
                                    <fo:block>Full Name</fo:block>
                                </fo:table-cell>
                                <fo:table-cell>
                                    <fo:block>Postal Code</fo:block>
                                </fo:table-cell>
                                <fo:table-cell>
                                    <fo:block>National ID</fo:block>
                                </fo:table-cell>
                                <fo:table-cell>
                                    <fo:block>Payment</fo:block>
                                </fo:table-cell>
                            </fo:table-row>
                            <xsl:for-each select="user-bill-data">
                                <fo:table-row>
                                    <fo:table-cell>
                                        <fo:block>
                                            <xsl:value-of select="full-name"/>
                                        </fo:block>
                                    </fo:table-cell>
                                    <fo:table-cell>
                                        <fo:block>
                                            <xsl:value-of select="postal-code"/>
                                        </fo:block>
                                    </fo:table-cell>
                                    <fo:table-cell>
                                        <fo:block>
                                            <xsl:value-of select="national-id"/>
                                        </fo:block>
                                    </fo:table-cell>
                                    <fo:table-cell>
                                        <fo:block>
                                            <xsl:value-of select="price"/>
                                        </fo:block>
                                    </fo:table-cell>
                                </fo:table-row>
                            </xsl:for-each>
                        </fo:table-body>
                    </fo:table>
                    <fo:block id="end-of-document">
                        <fo:instream-foreign-object>
                            <svg width="200mm" height="150mm" version="1.1" xmlns="http://www.w3.org/2000/svg">
                                <path d="M153 334
C153 334 151 334 151 334
C151 339 153 344 156 344
C164 344 171 339 171 334
C171 322 164 314 156 314
C142 314 131 322 131 334
C131 350 142 364 156 364
C175 364 191 350 191 334
C191 311 175 294 156 294
C131 294 111 311 111 334
C111 361 131 384 156 384
C186 384 211 361 211 334
C211 300 186 274 156 274" style="fill:yellow;stroke:red;stroke-width:2"/>
                            </svg>
                        </fo:instream-foreign-object>
                    </fo:block>
                </fo:flow>
            </fo:page-sequence>
        </fo:root>
    </xsl:template>
</xsl:stylesheet>

D-プロジェクトのディレクトリ構造

enter image description here

E-Pomファイル

<project xmlns="http://maven.Apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.Apache.org/POM/4.0.0 http://maven.Apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.levent.fopdemo</groupId>
    <artifactId>Apache-fop-demo</artifactId>
    <packaging>jar</packaging>
    <version>1.0-SNAPSHOT</version>
    <name>Apache-fop-demo</name>
    <url>http://maven.Apache.org</url>

    <properties>
        <fop.version>2.1</fop.version>
    </properties>

    <dependencies>      
        <!-- https://mvnrepository.com/artifact/org.Apache.xmlgraphics/fop -->
        <dependency>
            <groupId>org.Apache.xmlgraphics</groupId>
            <artifactId>fop</artifactId>
            <version>${fop.version}</version>
        </dependency>
    </dependencies>

    <build>
        <finalName>Apache Fop Demo</finalName>

        <plugins>
            <plugin>
                <groupId>org.Apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.5.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

F-デモコード:PdfGenerationDemo.Java

package com.levent.fopdemo;

import Java.io.File;
import Java.io.IOException;
import Java.io.OutputStream;

import javax.xml.transform.Result;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.sax.SAXResult;
import javax.xml.transform.stream.StreamSource;

import org.Apache.fop.apps.FOPException;
import org.Apache.fop.apps.FOUserAgent;
import org.Apache.fop.apps.Fop;
import org.Apache.fop.apps.FopFactory;
import org.Apache.fop.apps.MimeConstants;

public class PdfGenerationDemo 
{
    public static final String RESOURCES_DIR;
    public static final String OUTPUT_DIR;

    static {
        RESOURCES_DIR = "src//main//resources//";
        OUTPUT_DIR = "src//main//resources//output//";
    }

    public static void main( String[] args )
    {
        try {
            convertToPDF();
        } catch (FOPException | IOException | TransformerException e) {
            e.printStackTrace();
        }
    }

    public static void convertToPDF() throws IOException, FOPException, TransformerException {
        // the XSL FO file
        File xsltFile = new File(RESOURCES_DIR + "//template.xsl");
        // the XML file which provides the input
        StreamSource xmlSource = new StreamSource(new File(RESOURCES_DIR + "//data.xml"));
        // create an instance of fop factory
        FopFactory fopFactory = FopFactory.newInstance(new File(".").toURI());
        // a user agent is needed for transformation
        FOUserAgent foUserAgent = fopFactory.newFOUserAgent();
        // Setup output
        OutputStream out;
        out = new Java.io.FileOutputStream(OUTPUT_DIR + "//output.pdf");

        try {
            // Construct fop with desired output format
            Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, foUserAgent, out);

            // Setup XSLT
            TransformerFactory factory = TransformerFactory.newInstance();
            Transformer transformer = factory.newTransformer(new StreamSource(xsltFile));

            // Resulting SAX events (the generated FO) must be piped through to
            // FOP
            Result res = new SAXResult(fop.getDefaultHandler());

            // Start XSLT transformation and FOP processing
            // That's where the XML is first transformed to XSL-FO and then
            // PDF is created
            transformer.transform(xmlSource, res);
        } finally {
            out.close();
        }
    }
}

G-サンプル出力:output.pdf

enter image description here

23

Apacheプロジェクトをチェックすることもできます ここ

6
hakan

[〜#〜] birt [〜#〜] には、XML、DB、CSVなどからPDFを定義できるEclipse用のGUIがあります。

2
jeff porter

xhtmlrenderer プロジェクトを試してください。記事「 Flying SaucerとiTextで楽しさと利益を得るためにPDFを生成する 」を参照してください。

1
axelclk

変換としてPDF作成を行うことができる、そこにあるXSL-FOライブラリーを調べたいと思うかもしれません。リンクを見つけてみます。

1
Mitchel Sellers

XSL-FoをXMLに適用し、Javaトランスフォーマーで変換できます。

File xmlfile = new File(baseDir, xml);
File xsltfile = new File(baseDir, xsl);
File pdffile = new File(outDir, "ResultXMLPDF.pdf");

FopFactory fopFactory = FopFactory.newInstance();
FOUserAgent foUserAgent = fopFactory.newFOUserAgent();

OutputStream out = new Java.io.FileOutputStream(pdffile);
out = new Java.io.BufferedOutputStream(out);

try
{
    Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, foUserAgent, out);
    // Setup XSLT
    TransformerFactory factory = TransformerFactory.newInstance();
    Transformer transformer = factory.newTransformer(new StreamSource(xsltfile));

    transformer.setParameter("versionParam", "1.0");

    Source src = new StreamSource(xmlfile);

    Result res = new SAXResult(fop.getDefaultHandler());

    transformer.transform(src, res);

} finally {
    out.close();
}

System.out.println("Success!");
1
Yaroslav

JasperReportsを使用します。データベースまたはXMLからデータをプルできます。多くのフォーマットにエクスポートできます:pdf、Excel、htmlなど...

0
raffimd

後日、静的なPDFをAdobeのデザイナーで編集可能なフィールドを使用して作成し、次に一致するXDP XMLドキュメントを作成できます。

0
Dean J

XML、CSS、XHTMLなどはオープンスタンダードの「生きているエコシステム」で構成されていますが、XSL-FOは分離されたスタンダードです。

...歴史的に、XSL-FOとXSLTは双子の兄弟として作成されましたが、XSLTだけが「生きた標準」のままであり、XSL-FOは多くのDNAを独占的な(Adobe)標準に集中しています...現在は廃止されています。

厳密に言えば、XSL-FOは進化しない「放棄された方法」の一部であり、「生きたエコシステム」でレイアウトを表現する「新しい方法」であるCSSを無視します。

Java問題ではありません

この回答を参照 XMLまたはXHTMLでのCSS-pageの使用について。

0
Peter Krauss

これを行うには2つの方法があります。

  • 最初に、通常のPDFを作成できます。これは、読み戻されても元のXMLファイルの階層を提供しません。これについては、'Section 9.4.2 Parsing XML'/'iText in Action : Edition 2'

  • 次に、タグ付きのPDFを作成します。これには、XMLの階層とデータの両方が含まれます。これにより、PDFファイルとthisからXMLファイルを作成します(元のXMLファイルと完全に一致します)。この概念については、'15.2.3 Adding structure'/'iText in Action : Edition 2'

要件に基づいて、上記のいずれかの方法を使用できます。