From 7d8dfd1577528d432270df9fa2507cd0946924fc Mon Sep 17 00:00:00 2001 From: "Oliver.Warz@pdv.de" Date: Sun, 1 May 2022 12:45:05 +0200 Subject: [PATCH] 0.9.3 --- .gitignore | 22 + CHANGELOG | 30 + LICENSE | 4 +- README.md | 47 +- pom.xml | 134 ++++ src/main/java/de/pdv/apex/PdfServlet.java | 147 ++++ src/main/resources/samples/helloWorld.fo | 30 + src/main/webapp/META-INF/context.xml | 21 + src/main/webapp/WEB-INF/web.xml | 25 + src/main/webapp/index.jsp | 68 ++ .../java/de/pdv/apex/ExampleFO2PDFTest.java | 126 ++++ .../java/de/pdv/apex/ExampleXML2PDFTest.java | 87 +++ src/test/resources/samples/helloWorld.fo | 30 + .../resources/samples/kostenblatt_2014.xml | 685 +++++++++++++++++ .../resources/samples/kostenblatt_2014.xsl | 701 ++++++++++++++++++ 15 files changed, 2154 insertions(+), 3 deletions(-) create mode 100644 CHANGELOG create mode 100644 pom.xml create mode 100644 src/main/java/de/pdv/apex/PdfServlet.java create mode 100644 src/main/resources/samples/helloWorld.fo create mode 100644 src/main/webapp/META-INF/context.xml create mode 100644 src/main/webapp/WEB-INF/web.xml create mode 100644 src/main/webapp/index.jsp create mode 100644 src/test/java/de/pdv/apex/ExampleFO2PDFTest.java create mode 100644 src/test/java/de/pdv/apex/ExampleXML2PDFTest.java create mode 100644 src/test/resources/samples/helloWorld.fo create mode 100644 src/test/resources/samples/kostenblatt_2014.xml create mode 100644 src/test/resources/samples/kostenblatt_2014.xsl diff --git a/.gitignore b/.gitignore index a1c2a23..2fccb66 100644 --- a/.gitignore +++ b/.gitignore @@ -21,3 +21,25 @@ # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml hs_err_pid* + +*.bak +.adf +.data +.idea +**/.classpath +**/.project +**/.settings +**/build +**/dist +**/nbproject +**/target +**/*.log +**/nb-configuration.xml +**/rebel.xml +**/rebel-remote.xml +.gradle +**/*.iml +**/.factorypath +buildSrc +**/.idea +**/Debug diff --git a/CHANGELOG b/CHANGELOG new file mode 100644 index 0000000..579bdda --- /dev/null +++ b/CHANGELOG @@ -0,0 +1,30 @@ +# Changelog +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [Unreleased] + +## [0.9.3] - 2022-04-04 +### Changed +- uptake javamelody 1.91.0 +- uptake maven plugins + +## [0.9.2] - 2022-01-31 +### Added +- 2 tests + +### Changed +- cleanup samples +- uptake apache fop 2.7 +- uptake javamelody 1.90.0 + +## [0.9.1] - 2022-01-28 +### Added +- initial version +- apache fop 2.6 + +[Unreleased]: http://gitlab.pdv.lan/oliver1/fop4apex/compare/0.9.3...master +[0.9.3]: http://gitlab.pdv.lan/oliver1/fop4apex/compare/0.9.2...0.9.3 +[0.9.2]: hhttp://gitlab.pdv.lan/oliver1/fop4apex/-/tags/0.9.2 diff --git a/LICENSE b/LICENSE index 261eeb9..790b76e 100644 --- a/LICENSE +++ b/LICENSE @@ -178,7 +178,7 @@ APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" + boilerplate notice, with the fields enclosed by brackets "{}" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a @@ -186,7 +186,7 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright [yyyy] [name of copyright owner] + Copyright 2022 Oliver Warz Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/README.md b/README.md index a0c8d46..94f3b3c 100644 --- a/README.md +++ b/README.md @@ -1 +1,46 @@ -# fop4apex \ No newline at end of file +# fop4apex +Servlet for Oracle APEX to run PDF Reports based on Apache FOP + +Fahrdienst-Anwendung / Kostenblatt + +* Uses Apache FOP for rendering +https://xmlgraphics.apache.org/fop/ +* Uses JavaMelody for monitoring +https://github.com/javamelody/javamelody/wiki +* Use Java 8 LTS (also tested with Java 17) + +## Run tests +`mvn test` + +## Build +`mvn package verify` + +## Upgrade +* set new version in pom.xml +* check dependent libraries for updates +* run tests and build + +## Installation +* rename target/fop4apex*.war to fop4apex.war +* copy fop4apex.war to tomcat webapps folder +* Oracle APEX - Sample Settings + * PrintServer External (Apache FOP) + * Protocol HTTP / HTTPS + * Host 127.0.0.1 + * Port 8080 + * Script: /fop4apex/pdf + * Timeout 300 +### Debugging +Add to Tomcat logging.properties: +``` +org.apache.tomcat.util.http.Parameters.level = ALL +de.pdv.apex.level = ALL +``` + +### Deploy to tomcat 9.x (IntelliJ / Netbeans) +Run http://localhost:port/ + +Example: +* http://localhost:8080/fop4apex_war_exploded/ +* http://localhost:8080/fop4apex_war_exploded/monitoring + diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..c85a3b2 --- /dev/null +++ b/pom.xml @@ -0,0 +1,134 @@ + + + 4.0.0 + + de.pdv.apex + fop4apex + 0.9.3 + fop4apex + war + https://www.pdv.de + + + UTF-8 + 1.8 + 1.8 + 5.8.2 + + + + + javax.servlet + javax.servlet-api + 4.0.1 + provided + + + org.junit.jupiter + junit-jupiter-api + ${junit.version} + test + + + org.junit.jupiter + junit-jupiter-engine + ${junit.version} + test + + + + org.apache.pdfbox + pdfbox + 2.0.25 + test + + + + + org.apache.xmlgraphics + fop-core + 2.7 + compile + + + + + net.bull.javamelody + javamelody-core + 1.91.0 + compile + + + + + + org.apache.pdfbox + fontbox + 2.0.25 + compile + + + + commons-io + commons-io + 2.11.0 + compile + + + + commons-logging + commons-logging + 1.2 + compile + + + + + + + + org.apache.maven.plugins + maven-war-plugin + 3.3.2 + + + org.owasp + dependency-check-maven + 7.0.4 + + + + check + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 3.0.0-M6 + + + + + + \ No newline at end of file diff --git a/src/main/java/de/pdv/apex/PdfServlet.java b/src/main/java/de/pdv/apex/PdfServlet.java new file mode 100644 index 0000000..b0f1d2b --- /dev/null +++ b/src/main/java/de/pdv/apex/PdfServlet.java @@ -0,0 +1,147 @@ +package de.pdv.apex; + +import org.apache.fop.apps.FOUserAgent; +import org.apache.fop.apps.Fop; +import org.apache.fop.apps.FopFactory; +import org.apache.fop.apps.MimeConstants; + +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.xml.transform.Result; +import javax.xml.transform.Source; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.sax.SAXResult; +import javax.xml.transform.stream.StreamSource; +import java.io.*; +import java.util.logging.Level; +import java.util.logging.Logger; + + +/** + * @author oliver1 + */ +@WebServlet(name = "pdf", urlPatterns = {"/pdf"}) +public class PdfServlet extends HttpServlet { + private static final Logger logger = Logger.getLogger(PdfServlet.class.getName()); + + private final TransformerFactory tFactory = TransformerFactory.newInstance(); + + public void init() { + } + + // + + /** + * Handles the HTTP GET method. + * + * @param request servlet request + * @param response servlet response + */ + @Override + protected void doGet(HttpServletRequest request, HttpServletResponse response) + throws ServletException { + logger.log(Level.FINEST,"Finest output"); + logger.log(Level.FINER,"Finer output"); + logger.log(Level.FINE,"Fine output"); + logger.log(Level.INFO,"Info output"); + logger.log(Level.INFO,"doGet"); + try { + response.setContentType("application/pdf"); + // response.setDateHeader("Expires", System.currentTimeMillis() + cacheExpiringDuration * 1000); + FopFactory fopFactory = FopFactory.newInstance(new File(".").toURI()); + Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, response.getOutputStream()); + Transformer transformer = tFactory.newTransformer(); + InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("samples/helloWorld.fo"); + Source src = new StreamSource(inputStream); + Result res = new SAXResult(fop.getDefaultHandler()); + transformer.transform(src, res); + logger.log(Level.INFO,"Process complete"); + } catch (Exception ex) { + throw new ServletException(ex); + } + } + + + /** + * Handles the HTTP POST method. + * + * @param request servlet request + * @param response servlet response + * @throws ServletException if a servlet-specific error occurs + */ + @Override + protected void doPost(HttpServletRequest request, HttpServletResponse response) + throws ServletException { + ServletContext context = getServletContext(); + logger.log(Level.FINEST,"Finest output"); + logger.log(Level.FINER,"Finer output"); + logger.log(Level.FINE,"Fine output"); + logger.log(Level.INFO,"Info output"); + logger.log(Level.INFO,"doPost"); + try { + String contentType = request.getContentType(); + String templateFile = "template.fo"; + String templateData = "xml data"; + // String pdfFileName = ""; + + if (request.getParameter("template") != null) + templateFile = request.getParameter("template"); + if (request.getParameter("xml") != null) + templateData = request.getParameter("xml"); + logger.log(Level.FINEST,"Working directory: " + (new File("dummy1.txt")).getAbsolutePath()); + logger.log(Level.FINEST,"Template file: " + templateFile); + logger.log(Level.FINEST,"Template data: " + templateData); + logger.log(Level.FINEST,"Content type: " + contentType); + + String pdfFileName = "Kostenblatt.pdf"; + response.setContentType("application/pdf"); + response.setHeader("Content-disposition", "attachment; filename=" + pdfFileName); + // response.setDateHeader("Expires", System.currentTimeMillis() + cacheExpiringDuration * 1000); + FopFactory fopFactory = FopFactory.newInstance(new File(".").toURI()); + FOUserAgent foUserAgent = fopFactory.newFOUserAgent(); + // Construct fop with desired output format + Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, foUserAgent, response.getOutputStream()); + + // Setup XSLT + TransformerFactory factory = TransformerFactory.newInstance(); + Transformer transformer = factory.newTransformer( new StreamSource(new StringReader(templateFile))); + // Set the value of a in the stylesheet + transformer.setParameter("versionParam", "2.0"); + + // Setup input for XSLT transformation + Source src = new StreamSource(new StringReader(templateData)); + + // Resulting SAX events (the generated FO) must be piped through to FOP + Result res = new SAXResult(fop.getDefaultHandler()); + + // Start XSLT transformation and FOP processing + transformer.transform(src, res); + logger.log(Level.INFO,"Process complete"); + + } catch (Exception e) { + context.log(e.getMessage(), e); + throw new ServletException(e.getMessage()); + } + // processRequest(request, response); + } + + /** + * Returns a short description of the servlet. + * + * @return a String containing servlet description + */ + @Override + public String getServletInfo() { + return "APEX FOP Server"; + }// + + @Override + public void destroy() { + } + +} \ No newline at end of file diff --git a/src/main/resources/samples/helloWorld.fo b/src/main/resources/samples/helloWorld.fo new file mode 100644 index 0000000..d9345b5 --- /dev/null +++ b/src/main/resources/samples/helloWorld.fo @@ -0,0 +1,30 @@ + + + + + + + + + + + + Hello World! + + + diff --git a/src/main/webapp/META-INF/context.xml b/src/main/webapp/META-INF/context.xml new file mode 100644 index 0000000..b09d605 --- /dev/null +++ b/src/main/webapp/META-INF/context.xml @@ -0,0 +1,21 @@ + + + + + \ No newline at end of file diff --git a/src/main/webapp/WEB-INF/web.xml b/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 0000000..39b755f --- /dev/null +++ b/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,25 @@ + + + + javamelody + net.bull.javamelody.MonitoringFilter + true + + update-check-disabled + true + + + + javamelody + /* + REQUEST + ASYNC + + + net.bull.javamelody.SessionListener + + + \ No newline at end of file diff --git a/src/main/webapp/index.jsp b/src/main/webapp/index.jsp new file mode 100644 index 0000000..6274d83 --- /dev/null +++ b/src/main/webapp/index.jsp @@ -0,0 +1,68 @@ +<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %> + + + + Apache FOP for Oracle APEX + + + +

JSP - Apache FOP (Formatting Objects Processor) integration for Oracle APEX

+
+<%--suppress HtmlUnknownTarget --%> +pdf Servlet / Hello World / fo2pdf
+<%--suppress HtmlUnknownTarget --%> +JavaMelody Monitoring +

Sample APEX Settings

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParameterValue
PrintServerExternal (Apache FOP)
ProtocolHTTP / HTTPS
Host127.0.0.1
Port8080
Script${pageContext.request.contextPath}/pdf
Timeout300
+ +

Debugging

+ +# Add to logging.properties
+org.apache.tomcat.util.http.Parameters.level = ALL
+de.pdv.apex.level = ALL +
+ + +

Server Info

+Server Version: <%= application.getServerInfo() %>
+Servlet Version: <%= application.getMajorVersion() %>.<%= application.getMinorVersion() %>
+JSP Version: <%= JspFactory.getDefaultFactory().getEngineInfo().getSpecificationVersion() %>
+Web Application Context Path = ${pageContext.request.contextPath}
+
+ + \ No newline at end of file diff --git a/src/test/java/de/pdv/apex/ExampleFO2PDFTest.java b/src/test/java/de/pdv/apex/ExampleFO2PDFTest.java new file mode 100644 index 0000000..3c5d9d0 --- /dev/null +++ b/src/test/java/de/pdv/apex/ExampleFO2PDFTest.java @@ -0,0 +1,126 @@ +package de.pdv.apex; + +import org.apache.fop.apps.*; +import org.apache.pdfbox.pdmodel.PDDocument; +import org.apache.pdfbox.text.PDFTextStripper; +import org.apache.pdfbox.text.PDFTextStripperByArea; +import org.junit.jupiter.api.Test; + +import javax.xml.transform.Result; +import javax.xml.transform.Source; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.sax.SAXResult; +import javax.xml.transform.stream.StreamSource; +import java.io.*; +import java.nio.file.Files; +import java.util.List; + +class ExampleFO2PDFTest { + + // configure fopFactory as desired + private final FopFactory fopFactory = FopFactory.newInstance(new File(".").toURI()); + + /** + * Converts an FO file to a PDF file using FOP + * + * @param fo the FO file + * @param pdf the target PDF file + * @throws IOException In case of an I/O problem + */ + public void convertFO2PDFHelper(InputStream fo, File pdf) throws IOException { + + OutputStream out = null; + + try { + FOUserAgent foUserAgent = fopFactory.newFOUserAgent(); + // configure foUserAgent as desired + + // Setup output stream. Note: Using BufferedOutputStream + // for performance reasons (helpful with FileOutputStreams). + out = new FileOutputStream(pdf); + out = new BufferedOutputStream(out); + + // Construct fop with desired output format + Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, foUserAgent, out); + + // Setup JAXP using identity transformer + TransformerFactory factory = TransformerFactory.newInstance(); + Transformer transformer = factory.newTransformer(); // identity transformer + + // Setup input stream + Source src = new StreamSource(fo); + + // Resulting SAX events (the generated FO) must be piped through to FOP + Result res = new SAXResult(fop.getDefaultHandler()); + + // Start XSLT transformation and FOP processing + transformer.transform(src, res); + + // Result processing + FormattingResults foResults = fop.getResults(); + @SuppressWarnings("rawtypes") List pageSequences = foResults.getPageSequences(); + for (Object pageSequence : pageSequences) { + PageSequenceResults pageSequenceResults = (PageSequenceResults) pageSequence; + System.out.println("PageSequence " + + (String.valueOf(pageSequenceResults.getID()).length() > 0 + ? pageSequenceResults.getID() : "") + + " generated " + pageSequenceResults.getPageCount() + " pages."); + } + System.out.println("Generated " + foResults.getPageCount() + " pages in total."); + + } catch (Exception e) { + e.printStackTrace(System.err); + System.exit(-1); + } finally { + assert out != null; + out.close(); + } + } + + @Test + void convertFO2PDF() throws Exception { + System.out.println("FOP ExampleFO2PDF\n"); + System.out.println("Preparing..."); + + //Setup directories + File baseDir = new File("."); + File outDir = new File(baseDir, "target"); + boolean bSuccess = outDir.mkdirs(); + if (!bSuccess) + System.out.println("mkdirs result: false"); + + ExampleFO2PDFTest app = new ExampleFO2PDFTest(); + //Setup input and output files + InputStream inputStream = app.getClass().getClassLoader().getResourceAsStream("samples/helloWorld.fo"); + File pdfFile = new File(outDir, "ResultFO2PDF.pdf"); + + System.out.println("Input: XSL-FO (" + inputStream + ")"); + System.out.println("Output: PDF (" + pdfFile + ")"); + System.out.println(); + System.out.println("Transforming..."); + + app.convertFO2PDFHelper(inputStream, pdfFile); + + if (!pdfFile.exists()) + throw new Exception("result file missing"); + + try (PDDocument document = PDDocument.load(pdfFile)) { + document.getClass(); + if (!document.isEncrypted()) { + PDFTextStripperByArea stripper = new PDFTextStripperByArea(); + stripper.setSortByPosition(true); + PDFTextStripper tStripper = new PDFTextStripper(); + String pdfFileInText = tStripper.getText(document); + String lines[] = pdfFileInText.split("\\r?\\n"); + for (String line : lines) { + System.out.println(line); + } + System.out.println("Pages: " + document.getNumberOfPages()); + } + } + System.out.println("Filesize (Bytes): " + Files.size(pdfFile.toPath())); + System.out.println("Success!"); + } + +} \ No newline at end of file diff --git a/src/test/java/de/pdv/apex/ExampleXML2PDFTest.java b/src/test/java/de/pdv/apex/ExampleXML2PDFTest.java new file mode 100644 index 0000000..1f80fd7 --- /dev/null +++ b/src/test/java/de/pdv/apex/ExampleXML2PDFTest.java @@ -0,0 +1,87 @@ +package de.pdv.apex; + +import org.apache.fop.apps.FOUserAgent; +import org.apache.fop.apps.Fop; +import org.apache.fop.apps.FopFactory; +import org.apache.fop.apps.MimeConstants; +import org.apache.pdfbox.pdmodel.PDDocument; +import org.junit.jupiter.api.Test; + +import javax.xml.transform.Result; +import javax.xml.transform.Source; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.sax.SAXResult; +import javax.xml.transform.stream.StreamSource; +import java.io.File; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.file.Files; + +class ExampleXML2PDFTest { + + @Test + void convertXML2PDF() throws Exception { + System.out.println("FOP ExampleXML2PDF\n"); + System.out.println("Preparing..."); + + // Setup directories + File baseDir = new File("."); + File outDir = new File(baseDir, "target"); + boolean bSuccess = outDir.mkdirs(); + if (!bSuccess) + System.out.println("mkdirs result: false"); + + ExampleXML2PDFTest app = new ExampleXML2PDFTest(); + // Setup input and output files + InputStream xsltFile = app.getClass().getClassLoader().getResourceAsStream("samples/kostenblatt_2014.xsl"); + InputStream xmlFile = app.getClass().getClassLoader().getResourceAsStream("samples/kostenblatt_2014.xml"); + File pdfFile = new File(outDir, "ResultXML2PDF.pdf"); + + System.out.println("Input: XML (" + xmlFile + ")"); + System.out.println("Stylesheet: " + xsltFile); + System.out.println("Output: PDF (" + pdfFile + ")"); + System.out.println(); + System.out.println("Transforming..."); + + // configure fopFactory as desired + final FopFactory fopFactory = FopFactory.newInstance(new File(".").toURI()); + + FOUserAgent foUserAgent = fopFactory.newFOUserAgent(); + // configure foUserAgent as desired + + // Setup output + OutputStream out = new java.io.FileOutputStream(pdfFile); + out = new java.io.BufferedOutputStream(out); + + // 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)); + + // Set the value of a in the stylesheet + transformer.setParameter("versionParam", "2.0"); + + // Setup input for XSLT transformation + Source src = new StreamSource(xmlFile); + + // Resulting SAX events (the generated FO) must be piped through to FOP + Result res = new SAXResult(fop.getDefaultHandler()); + + // Start XSLT transformation and FOP processing + transformer.transform(src, res); + + //close + out.close(); + + if (!pdfFile.exists()) + throw new Exception("result file missing"); + + PDDocument document = PDDocument.load(pdfFile); + System.out.println("Pages: " + document.getNumberOfPages()); + System.out.println("Filesize (Bytes): " + Files.size(pdfFile.toPath())); + System.out.println("Success!"); + } +} \ No newline at end of file diff --git a/src/test/resources/samples/helloWorld.fo b/src/test/resources/samples/helloWorld.fo new file mode 100644 index 0000000..d9345b5 --- /dev/null +++ b/src/test/resources/samples/helloWorld.fo @@ -0,0 +1,30 @@ + + + + + + + + + + + + Hello World! + + + diff --git a/src/test/resources/samples/kostenblatt_2014.xml b/src/test/resources/samples/kostenblatt_2014.xml new file mode 100644 index 0000000..89ea899 --- /dev/null +++ b/src/test/resources/samples/kostenblatt_2014.xml @@ -0,0 +1,685 @@ + + + + + Dienstag , 18. Januar 2022 + 2019 + 605 + THL 2-1 + BMW 730d xDrive (Leasing-PKW) + WBA7C41010BR89892 + 01.10.2018 + + 01.10.2018 + nein + + 0,00 + 226,10 + Regio/Fern + Diesel + F + 9.361 + 12.193 + 8 + 4,49 + 0,00 + A07 + 7 + Arbeitstage + (AT) + 23 + + + + + + + + + + + + 23 + + + Dienstag , 18. Januar 2022 + 2019 + 605 + THL 2-1 + BMW 730d xDrive (Leasing-PKW) + WBA7C41010BR89892 + 01.10.2018 + + 01.10.2018 + nein + + 0,00 + 226,10 + Regio/Fern + Diesel + F + 9.361 + 12.193 + 8 + 4,49 + 0,00 + A08 + 8 + Einsatztage + (ET) + 18 + + + + + + + + + + + + 18 + + + Dienstag , 18. Januar 2022 + 2019 + 605 + THL 2-1 + BMW 730d xDrive (Leasing-PKW) + WBA7C41010BR89892 + 01.10.2018 + + 01.10.2018 + nein + + 0,00 + 226,10 + Regio/Fern + Diesel + F + 9.361 + 12.193 + 8 + 4,49 + 0,00 + A09 + 9 + Nutzungsfrequenz + (ETx100/AT) + 78 + + + + + + + + + + + + 78 + + + Dienstag , 18. Januar 2022 + 2019 + 605 + THL 2-1 + BMW 730d xDrive (Leasing-PKW) + WBA7C41010BR89892 + 01.10.2018 + + 01.10.2018 + nein + + 0,00 + 226,10 + Regio/Fern + Diesel + F + 9.361 + 12.193 + 8 + 4,49 + 0,00 + A10 + 10 + gefahrene km + + 2.832 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 2.832 + + + Dienstag , 18. Januar 2022 + 2019 + 605 + THL 2-1 + BMW 730d xDrive (Leasing-PKW) + WBA7C41010BR89892 + 01.10.2018 + + 01.10.2018 + nein + + 0,00 + 226,10 + Regio/Fern + Diesel + F + 9.361 + 12.193 + 8 + 4,49 + 0,00 + A11 + 11 + Kraftstoff getankt + (l/kg) + 241,24 + 0,00 + 0,00 + 0,00 + 0,00 + 0,00 + 0,00 + 0,00 + 0,00 + 0,00 + 0,00 + 0,00 + 241,24 + + + Dienstag , 18. Januar 2022 + 2019 + 605 + THL 2-1 + BMW 730d xDrive (Leasing-PKW) + WBA7C41010BR89892 + 01.10.2018 + + 01.10.2018 + nein + + 0,00 + 226,10 + Regio/Fern + Diesel + F + 9.361 + 12.193 + 8 + 4,49 + 0,00 + A12 + 12 + Kraftstoff bezahlt + (EUR je l/kg) + 285,72 + 0,00 + 0,00 + 0,00 + 0,00 + 0,00 + 0,00 + 0,00 + 0,00 + 0,00 + 0,00 + 0,00 + 285,72 + + + Dienstag , 18. Januar 2022 + 2019 + 605 + THL 2-1 + BMW 730d xDrive (Leasing-PKW) + WBA7C41010BR89892 + 01.10.2018 + + 01.10.2018 + nein + + 0,00 + 226,10 + Regio/Fern + Diesel + F + 9.361 + 12.193 + 8 + 4,49 + 0,00 + A13 + 13 + Kraftstoff Liter-Preis + (EUR je l/kg) + 1,18 + + + + + + + + + + + + 1,18 + + + Dienstag , 18. Januar 2022 + 2019 + 605 + THL 2-1 + BMW 730d xDrive (Leasing-PKW) + WBA7C41010BR89892 + 01.10.2018 + + 01.10.2018 + nein + + 0,00 + 226,10 + Regio/Fern + Diesel + F + 9.361 + 12.193 + 8 + 4,49 + 0,00 + A14 + 14 + Kraftstoff Verbrauch + (l je 100 km) + 8,52 + + + + + + + + + + + + 8,52 + + + Dienstag , 18. Januar 2022 + 2019 + 605 + THL 2-1 + BMW 730d xDrive (Leasing-PKW) + WBA7C41010BR89892 + 01.10.2018 + + 01.10.2018 + nein + + 0,00 + 226,10 + Regio/Fern + Diesel + F + 9.361 + 12.193 + 8 + 4,49 + 0,00 + A15 + 15 + Öl nachgefüllt + (l) + 0,00 + 0,00 + 0,00 + 0,00 + 0,00 + 0,00 + 0,00 + 0,00 + 0,00 + 0,00 + 0,00 + 0,00 + 0,00 + + + Dienstag , 18. Januar 2022 + 2019 + 605 + THL 2-1 + BMW 730d xDrive (Leasing-PKW) + WBA7C41010BR89892 + 01.10.2018 + + 01.10.2018 + nein + + 0,00 + 226,10 + Regio/Fern + Diesel + F + 9.361 + 12.193 + 8 + 4,49 + 0,00 + A16 + 16 + Öl bezahlt + (EUR) + 0,00 + 0,00 + 0,00 + 0,00 + 0,00 + 0,00 + 0,00 + 0,00 + 0,00 + 0,00 + 0,00 + 0,00 + 0,00 + + + Dienstag , 18. Januar 2022 + 2019 + 605 + THL 2-1 + BMW 730d xDrive (Leasing-PKW) + WBA7C41010BR89892 + 01.10.2018 + + 01.10.2018 + nein + + 0,00 + 226,10 + Regio/Fern + Diesel + F + 9.361 + 12.193 + 8 + 4,49 + 0,00 + A17 + 17 + Kosten Reparatur/Insp. + (EUR) + 0,00 + 0,00 + 0,00 + 0,00 + 0,00 + 0,00 + 0,00 + 0,00 + 0,00 + 0,00 + 0,00 + 0,00 + 0,00 + + + Dienstag , 18. Januar 2022 + 2019 + 605 + THL 2-1 + BMW 730d xDrive (Leasing-PKW) + WBA7C41010BR89892 + 01.10.2018 + + 01.10.2018 + nein + + 0,00 + 226,10 + Regio/Fern + Diesel + F + 9.361 + 12.193 + 8 + 4,49 + 0,00 + A18 + 18 + Kosten Zubehör + (EUR) + 38,56 + 0,00 + 0,00 + 0,00 + 0,00 + 0,00 + 0,00 + 0,00 + 0,00 + 0,00 + 0,00 + 0,00 + 38,56 + + + Dienstag , 18. Januar 2022 + 2019 + 605 + THL 2-1 + BMW 730d xDrive (Leasing-PKW) + WBA7C41010BR89892 + 01.10.2018 + + 01.10.2018 + nein + + 0,00 + 226,10 + Regio/Fern + Diesel + F + 9.361 + 12.193 + 8 + 4,49 + 0,00 + A19 + 19 + Kraftfahrzeugsteuer + (EUR) + 0,00 + 0,00 + 0,00 + 0,00 + 0,00 + 0,00 + 0,00 + 0,00 + 0,00 + 0,00 + 0,00 + 0,00 + 0,00 + + + Dienstag , 18. Januar 2022 + 2019 + 605 + THL 2-1 + BMW 730d xDrive (Leasing-PKW) + WBA7C41010BR89892 + 01.10.2018 + + 01.10.2018 + nein + + 0,00 + 226,10 + Regio/Fern + Diesel + F + 9.361 + 12.193 + 8 + 4,49 + 0,00 + A20 + 20 + Kosten Leasingrate + (EUR) + 226,10 + 226,10 + 226,10 + 226,10 + 226,10 + 226,10 + 226,10 + 226,10 + 226,10 + 0,00 + 0,00 + 0,00 + 2.034,90 + + + Dienstag , 18. Januar 2022 + 2019 + 605 + THL 2-1 + BMW 730d xDrive (Leasing-PKW) + WBA7C41010BR89892 + 01.10.2018 + + 01.10.2018 + nein + + 0,00 + 226,10 + Regio/Fern + Diesel + F + 9.361 + 12.193 + 8 + 4,49 + 0,00 + A21 + 21 + Summe aller Kosten + (EUR) + 554,87 + 230,59 + 230,59 + 230,59 + 230,59 + 226,10 + 230,59 + 230,59 + 226,10 + 0,00 + 0,00 + 0,00 + 2.390,61 + + + Dienstag , 18. Januar 2022 + 2019 + 605 + THL 2-1 + BMW 730d xDrive (Leasing-PKW) + WBA7C41010BR89892 + 01.10.2018 + + 01.10.2018 + nein + + 0,00 + 226,10 + Regio/Fern + Diesel + F + 9.361 + 12.193 + 8 + 4,49 + 0,00 + A22 + 22 + km-Kosten + (EUR/km) + 0,20 + + + + + + + + + + + + 0,84 + + + Dienstag , 18. Januar 2022 + 2019 + 605 + THL 2-1 + BMW 730d xDrive (Leasing-PKW) + WBA7C41010BR89892 + 01.10.2018 + + 01.10.2018 + nein + + 0,00 + 226,10 + Regio/Fern + Diesel + F + 9.361 + 12.193 + 8 + 4,49 + 0,00 + A23 + 23 + Kosten pro ET + (EUR/ET) + 30,83 + + + + + + + + + + + + 132,81 + + + \ No newline at end of file diff --git a/src/test/resources/samples/kostenblatt_2014.xsl b/src/test/resources/samples/kostenblatt_2014.xsl new file mode 100644 index 0000000..ac4172e --- /dev/null +++ b/src/test/resources/samples/kostenblatt_2014.xsl @@ -0,0 +1,701 @@ + + + + + + + + + 0.25pt + 0.25pt + + + start + 2 + 0.0pt + preserve + 0.0pt + 0.0pt + 0.0pt + 0.0pt + 2 + + + left + + + center + + + right + + + right + 5.4pt + 5.4pt + + + 5.4pt + 23.4pt + + + 13.872pt + 5.4pt + + + 5.4pt + + + + + + + + + 13.872pt + + + false + + + solid + solid + + + 5.15pt + top + 0.0pt + 5.15pt + 1 + 0.0pt + 0.0pt + + + + + + 7pt + 0.5pt + solid + black + + + 7pt + 16pt + 1mm + 1mm + + + 6pt + 16pt + 1mm + 1mm + italic + + + 8pt + 16pt + 1mm + 1mm + + + 1mm + 1mm + + + 1mm + 1mm + + + + 8.0pt + 8.0pt + bold + Helvetica + 0.5pt + solid + black + #d6d6d6 + bold + + + 6.0pt + 6.0pt + 0.5pt + solid + black + #d6d6d6 + + + 14.0pt + 14.0pt + bold + Helvetica + 0.5pt + solid + black + black + + + 14.0pt + 14.0pt + bold + Helvetica + 0.0pt + solid + black + red + + + 3pt + 3pt + bold + Helvetica + 0.0pt + none + black + black + + + 8.0pt + 8.0pt + Helvetica + 0.5pt + solid + black + + + 7pt + 0.5pt + solid + black + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Amtliches Kennzeichen + + + + + + Jahr + + + + + + + + + + + + + Dienstfahrzeug-Kostenblatt + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + allgemeine Angaben + + + + + + + 1 + + + Eigentümer + + + + + + LAND + + + Halterdienststelle + + + TMIL + + + Nutzung + + + (Nah/Fern) + + + + + + + + + + 2 + + + Fahrzeugart und -typ + + + + + + + + + + + Kraftstoffart + + + + + + + + Fahrzeug-Ident-Nr + + + + + + + + + + + 3 + + + Erstzulassung + + + (Datum) + + + + + + + + Übernahme + + + + + + + + Aussonderung + + + + + + + + + + + 4 + + + Anschaffungskosten + + + (EUR) + + + + + + + + KFZ-Steuer + + + (EUR/Jahr) + + + + + + + + Kosten GEZ + + + (EUR/Monat) + + + + + + + + + + + 5 + + + überwiegend Selbstfahrer? + + + + + + + + Leasingrate + + + (EUR/Monat) + + + + + + + + Funk + + + (EUR/Monat) + + + + + + + + + + + 6 + + + km-Stand Jahresanfang + + + + + + + + km-Stand Jahresende + + + + + + + + Auslastungsquote (p) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Kfz-RL (Anlage 2) (c) 12.2015 TFM + + + + + + + + + + + + + + + + + + + + + + + + + + + Einsatz + + + Monat + + + Jan + + + Feb + + + Mrz + + + Apr + + + Mai + + + Jun + + + Jul + + + Aug + + + Sep + + + Okt + + + Nov + + + Dez + + + Summen + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +