Commit 4e016afe by Patryk Czarnik

Obsługa PDF - lista

parent b020b8ff
...@@ -42,5 +42,16 @@ ...@@ -42,5 +42,16 @@
<version>42.5.0</version> <version>42.5.0</version>
<scope>runtime</scope> <scope>runtime</scope>
</dependency> </dependency>
<dependency>
<groupId>org.apache.xmlgraphics</groupId>
<artifactId>fop</artifactId>
<version>2.7</version>
<exclusions>
<exclusion>
<groupId>xml-apis</groupId>
<artifactId>xml-apis</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies> </dependencies>
</project> </project>
...@@ -2,16 +2,12 @@ package sklep.rest; ...@@ -2,16 +2,12 @@ package sklep.rest;
import javax.ws.rs.GET; import javax.ws.rs.GET;
import javax.ws.rs.Path; import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces; import javax.ws.rs.Produces;
import sklep.db.DBConnection; import sklep.db.DBConnection;
import sklep.db.DBException; import sklep.db.DBException;
import sklep.db.ProductDAO; import sklep.db.ProductDAO;
import sklep.db.RecordNotFound;
import sklep.model.Product;
import sklep.model.ProductList; import sklep.model.ProductList;
import sklep.photo.PhotoUtil;
@Path("/products.pdf") @Path("/products.pdf")
@Produces("application/pdf") @Produces("application/pdf")
...@@ -24,21 +20,4 @@ public class RProductsPDF { ...@@ -24,21 +20,4 @@ public class RProductsPDF {
return new ProductList(productDAO.readAll()); return new ProductList(productDAO.readAll());
} }
} }
@GET
@Path("/{id}")
public Product readOne(@PathParam("id") int productId) throws DBException, RecordNotFound {
try(DBConnection db = DBConnection.open()) {
ProductDAO productDAO = db.productDAO();
return productDAO.findById(productId);
}
}
@GET
@Path("/{id}/photo")
@Produces("image/jpeg")
public byte[] getPhoto(@PathParam("id") int productId) throws DBException, RecordNotFound {
return PhotoUtil.readBytes(productId);
}
} }
package sklep.rest.ext;
import java.io.BufferedOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URI;
import javax.servlet.ServletContext;
import javax.ws.rs.WebApplicationException;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.util.JAXBSource;
import javax.xml.transform.Result;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.sax.SAXResult;
import javax.xml.transform.stream.StreamSource;
import org.apache.fop.apps.Fop;
import org.apache.fop.apps.FopFactory;
import org.apache.xmlgraphics.util.MimeConstants;
public class ObslugaXSL {
private ServletContext servletContext;
public ObslugaXSL(ServletContext servletContext) {
this.servletContext = servletContext;
}
// obiekt -(za pomocą JAXB)-> XML -(za pomocą transformera)-> XML(XSL-FO)
// --(za pomocą Apache FOP)-> PDF -> output
public void wypiszPDF(Object obj, OutputStream output) {
try(InputStream configStream = servletContext.getResourceAsStream("WEB-INF/fop-conf.xml")) {
JAXBContext ctx = JAXBContext.newInstance(obj.getClass());
JAXBSource src = new JAXBSource(ctx, obj);
FopFactory fopFactory = FopFactory.newInstance(new URI(""), configStream);
try(BufferedOutputStream pdfOut = new BufferedOutputStream(output)) {
Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, pdfOut);
TransformerFactory tf = TransformerFactory.newInstance();
StreamSource xsl = new StreamSource(servletContext.getResourceAsStream("WEB-INF/sklep-fo.xsl"));
Transformer tr = tf.newTransformer(xsl);
Result res = new SAXResult(fop.getDefaultHandler());
tr.transform(src, res);
}
} catch (Exception e) {
e.printStackTrace();
throw new WebApplicationException("Problem FOP " + e.getMessage(), e, 500);
}
}
}
...@@ -5,7 +5,9 @@ import java.io.OutputStream; ...@@ -5,7 +5,9 @@ import java.io.OutputStream;
import java.lang.annotation.Annotation; import java.lang.annotation.Annotation;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import javax.servlet.ServletContext;
import javax.ws.rs.WebApplicationException; import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.ext.MessageBodyWriter; import javax.ws.rs.ext.MessageBodyWriter;
...@@ -15,19 +17,22 @@ import sklep.model.ProductList; ...@@ -15,19 +17,22 @@ import sklep.model.ProductList;
@Provider @Provider
public class PDFWriter implements MessageBodyWriter<ProductList> { public class PDFWriter implements MessageBodyWriter<ProductList> {
private static final MediaType PDF_TYPE = new MediaType("application", "pdf");
@Context
private ServletContext servletContext;
@Override @Override
public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) { public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
// TODO Auto-generated method stub return (type == ProductList.class) && PDF_TYPE.isCompatible(mediaType);
return true;
} }
@Override @Override
public void writeTo(ProductList lista, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType, public void writeTo(ProductList lista, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType,
MultivaluedMap<String, Object> httpHeaders, OutputStream output) MultivaluedMap<String, Object> httpHeaders, OutputStream output)
throws IOException, WebApplicationException { throws IOException, WebApplicationException {
// TODO Auto-generated method stub ObslugaXSL obslugaXSL = new ObslugaXSL(servletContext);
obslugaXSL.wypiszPDF(lista, output);
} }
} }
<?xml version="1.0"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<!-- $Id: fop.xconf 447325 2006-09-18 08:55:33Z jeremias $ -->
<!--
This is an example configuration file for FOP.
This file contains the same settings as the default values
and will have no effect if used unchanged.
Relative config url's will be resolved relative to
the location of this file.
-->
<!-- NOTE: This is the version of the configuration -->
<fop version="1.0">
<!-- Base URL for resolving relative URLs -->
<base>.</base>
<!-- Source resolution in dpi (dots/pixels per inch) for determining the size of pixels in SVG and bitmap images, default: 72dpi -->
<source-resolution>72</source-resolution>
<!-- Target resolution in dpi (dots/pixels per inch) for specifying the target resolution for generated bitmaps, default: 72dpi -->
<target-resolution>72</target-resolution>
<!-- Default page-height and page-width, in case
value is specified as auto -->
<default-page-settings height="11in" width="8.26in"/>
<!-- Information for specific renderers -->
<!-- Uses renderer mime type for renderers -->
<renderers>
<renderer mime="application/pdf">
<filterList>
<!-- provides compression using zlib flate (default is on) -->
<value>flate</value>
<!-- encodes binary data into printable ascii characters (default off)
This provides about a 4:5 expansion of data size -->
<!-- <value>ascii-85</value> -->
<!-- encodes binary data with hex representation (default off)
This filter is not recommended as it doubles the data size -->
<!-- <value>ascii-hex</value> -->
</filterList>
<fonts>
<!-- embedded fonts -->
<!--
This information must exactly match the font specified
in the fo file. Otherwise it will use a default font.
For example,
<fo:inline font-family="Arial" font-weight="bold" font-style="normal">
Arial-normal-normal font
</fo:inline>
for the font triplet specified by:
<font-triplet name="Arial" style="normal" weight="bold"/>
If you do not want to embed the font in the pdf document
then do not include the "embed-url" attribute.
The font will be needed where the document is viewed
for it to be displayed properly.
possible styles: normal | italic | oblique | backslant
possible weights: normal | bold | 100 | 200 | 300 | 400
| 500 | 600 | 700 | 800 | 900
(normal = 400, bold = 700)
-->
<!--
<font kerning="yes" embed-url="/usr/share/fonts/truetype/msttcorefonts/arial.ttf">
<font-triplet name="Arial" style="normal" weight="normal"/>
<font-triplet name="ArialMT" style="normal" weight="normal"/>
</font>
<font kerning="yes" embed-url="/usr/share/fonts/truetype/msttcorefonts/arial.ttf">
<font-triplet name="Arial" style="normal" weight="normal"/>
<font-triplet name="ArialMT" style="normal" weight="normal"/>
</font>
-->
<!-- PC -->
<directory recursive="true">/usr/share/fonts/truetype/</directory>
<directory recursive="true">C:\Windows\Fonts</directory>
</fonts>
<!-- This option lets you specify additional options on an XML handler -->
<!--xml-handler namespace="http://www.w3.org/2000/svg">
<stroke-text>false</stroke-text>
</xml-handler-->
</renderer>
<renderer mime="application/postscript">
<!-- This option forces the PS renderer to rotate landscape pages -->
<!--auto-rotate-landscape>true</auto-rotate-landscape-->
<!-- This option lets you specify additional options on an XML handler -->
<!--xml-handler namespace="http://www.w3.org/2000/svg">
<stroke-text>false</stroke-text>
</xml-handler-->
</renderer>
<renderer mime="application/vnd.hp-PCL">
</renderer>
<!-- MIF does not have a renderer
<renderer mime="application/vnd.mif">
</renderer>
-->
<renderer mime="image/svg+xml">
<format type="paginated"/>
<link value="true"/>
<strokeText value="false"/>
</renderer>
<renderer mime="application/awt">
</renderer>
<renderer mime="image/png">
<!--transparent-page-background>true</transparent-page-background-->
</renderer>
<renderer mime="image/tiff">
<!--transparent-page-background>true</transparent-page-background-->
<!--compression>CCITT T.6</compression-->
</renderer>
<renderer mime="text/xml">
</renderer>
<!-- RTF does not have a renderer
<renderer mime="text/rtf">
</renderer>
-->
<renderer mime="text/plain">
<pageSize columns="80"/>
</renderer>
</renderers>
</fop>
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format">
<xsl:output method="xml" encoding="utf-8" />
<xsl:template match="/">
<fo:root font-family="Arial">
<fo:layout-master-set>
<fo:simple-page-master master-name="A4"
page-width="210mm" page-height="297mm" margin-top="1cm"
margin-bottom="1cm" margin-left="1.5cm" margin-right="1.5cm">
<fo:region-body margin="2cm" />
</fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence master-reference="A4">
<fo:flow flow-name="xsl-region-body">
<xsl:apply-templates />
<fo:block/>
</fo:flow>
</fo:page-sequence>
</fo:root>
</xsl:template>
<xsl:template match="product">
<fo:block-container space-before.minimum="0.5em"
page-break-inside="avoid">
<fo:block>
<xsl:text>Produkt nr </xsl:text>
<xsl:value-of select="@id" />
<xsl:text>.</xsl:text>
</fo:block>
<fo:block-container margin="1em"
border-style="solid" border-width="2.5pt" padding="3pt"
border-color="#2233AA">
<fo:block font-weight="bold" font-size="14pt"
margin-bottom="1em" color="#FF2244">
<xsl:apply-templates select="product-name" />
</fo:block>
<fo:block font-weight="bold" color="green">
<xsl:text>Cena: </xsl:text>
<xsl:value-of select="price" />
</fo:block>
<fo:block color="green">
<xsl:text>VAT: </xsl:text>
<fo:inline font-style="italic">
<xsl:value-of select="vat * 100" />
<xsl:text>%</xsl:text>
</fo:inline>
</fo:block>
<fo:block font-size="12pt" margin-bottom="1em">
<xsl:apply-templates select="description" />
</fo:block>
</fo:block-container>
</fo:block-container>
</xsl:template>
</xsl:stylesheet>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment