فهرست منبع

Merge pull request #1 from madmuffin1/master

load template from string, return PDF to byte array
Patrick Brückner 10 سال پیش
والد
کامیت
661e84965c

+ 2 - 0
.gitignore

@@ -1 +1,3 @@
 target/
+*.iml
+*.idea

+ 15 - 2
pom.xml

@@ -3,7 +3,7 @@
 	<modelVersion>4.0.0</modelVersion>
 	<groupId>br.eti.mertz</groupId>
 	<artifactId>java-wkhtmltopdf-wrapper</artifactId>
-	<version>0.0.1-SNAPSHOT</version>
+	<version>0.0.2-SNAPSHOT</version>
 
 	<dependencies>
 		<dependency>
@@ -12,6 +12,19 @@
 			<version>1.12.6</version>
 		</dependency>
 
-	</dependencies>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <version>4.11</version>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.pdfbox</groupId>
+            <artifactId>pdfbox</artifactId>
+            <version>1.8.9</version>
+        </dependency>
+
+    </dependencies>
 
 </project>

+ 3 - 3
src/main/java/br/eti/mertz/wkhtmltopdf/wrapper/Command.java

@@ -4,11 +4,11 @@ package br.eti.mertz.wkhtmltopdf.wrapper;
 public class Command {
 	
 	public static void main(String[] args) {
+
 		Pdf pdf = new Pdf();
-		
-		pdf.addParam(new Param("enable-javascript"), new Param("html-header", "file:///lala.html"));
-		
+		pdf.addParam(new Param("--enable-javascript"), new Param("--html-header", "file:///lala.html"));
 		System.out.println(pdf);
+
 	}
 
 }

+ 65 - 19
src/main/java/br/eti/mertz/wkhtmltopdf/wrapper/Pdf.java

@@ -1,7 +1,6 @@
 package br.eti.mertz.wkhtmltopdf.wrapper;
 
-import java.io.File;
-import java.io.IOException;
+import java.io.*;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
@@ -12,11 +11,15 @@ import lombok.Data;
 @Data
 public class Pdf implements PdfService {
 
-	private String wkhtmlpdf;
+    static final String STDOUT = "-";
+
+	private String command;
 	private List<Param> params;
+	private String htmlInput = null;
+    private boolean htmlFromString = false;
 
 	public Pdf(String wkhtmltopdf, List<Param> params) {
-		this.wkhtmlpdf = wkhtmltopdf;
+		this.command = wkhtmltopdf;
 		this.params = params;
 	}
 
@@ -32,11 +35,9 @@ public class Pdf implements PdfService {
 		this("wkhtmltopdf", new ArrayList<Param>());
 	}
 
-	/**
-	 * TODO Add a HTML file, a HTML string or a page from a URL
-	 */
-	public void addPage(String page) {
-		// TODO Auto-generated method stub
+	public void addHtmlInput(String input) {
+        this.htmlFromString = true;
+        this.htmlInput = input;
 	}
 
 	/**
@@ -64,27 +65,72 @@ public class Pdf implements PdfService {
 	}
 
 	/**
-	 * TODO save file and returns
-	 * 
 	 * @throws IOException
 	 * @throws InterruptedException
 	 */
 	public File saveAs(String path) throws IOException, InterruptedException {
-		Runtime rt = Runtime.getRuntime();
-		Process proc = rt.exec(this.toString() + path);
-
-		proc.waitFor();
-
-		return new File(path);
+        File file = new File(path);
+        getPDF(path);
+        return file;
 	}
 
-	public String toString() {
+    public File saveAs(String path, byte[] document) throws IOException {
+        File file = new File(path);
+
+        BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(file));
+        bufferedOutputStream.write(document);
+        bufferedOutputStream.flush();
+        bufferedOutputStream.close();
+
+        return file;
+    }
+
+    public byte[] getPDF(String path) throws IOException, InterruptedException {
+        Runtime runtime = Runtime.getRuntime();
+        if(htmlFromString && !this.params.contains(new Param("-"))) {
+            this.addParam(new Param("-"));
+        }
+        String command = this.commandWithParameters() + Symbol.separator + path;
+        Process process = runtime.exec(command);
+        if(htmlFromString) {
+            OutputStream stdInStream = process.getOutputStream();
+            stdInStream.write(htmlInput.getBytes("UTF-8"));
+            stdInStream.close();
+        }
+        InputStream stdOutStream = process.getInputStream();
+        InputStream stdErrStream = process.getErrorStream();
+        process.waitFor();
+
+        ByteArrayOutputStream stdOut = new ByteArrayOutputStream();
+        ByteArrayOutputStream stdErr = new ByteArrayOutputStream();
+
+        while(stdOutStream.available()>0) {
+            stdOut.write((char) stdOutStream.read());
+        }
+        stdOutStream.close();
+        while(stdErrStream.available()>0) {
+            stdErr.write((char) stdErrStream.read());
+        }
+        stdErrStream.close();
+
+        if(process.exitValue() != 0) {
+            throw new RuntimeException("Process (" + command + ") exited with status code " + process.exitValue() + ":\n"+new String(stdErr.toByteArray()));
+        }
+
+        return stdOut.toByteArray();
+    }
+
+    public byte[] getPDF() throws IOException, InterruptedException {
+        return getPDF(STDOUT);
+    }
+
+	public String commandWithParameters() {
 		StringBuilder sb = new StringBuilder();
 		for (Param param : params) {
 			sb.append(param);
 		}
 
-		return new StringBuilder(wkhtmlpdf).append(sb.toString()).toString();
+		return command + sb.toString();
 	}
 
 	public void addParam(GlobalOption option) {

+ 5 - 4
src/main/java/br/eti/mertz/wkhtmltopdf/wrapper/PdfService.java

@@ -5,12 +5,13 @@ import java.io.IOException;
 
 public interface PdfService {
 	
-	public void addPage(String page);
+	void addHtmlInput(String page);
 	
-	public void addCover(String cover);
+	void addCover(String cover);
 	
-	public void addToc();
+	void addToc();
 	
-	public File saveAs(String path) throws IOException, InterruptedException;
+	File saveAs(String path) throws IOException, InterruptedException;
 
+	byte[] getPDF() throws IOException, InterruptedException;
 }

+ 2 - 2
src/main/java/br/eti/mertz/wkhtmltopdf/wrapper/Symbol.java

@@ -2,11 +2,11 @@ package br.eti.mertz.wkhtmltopdf.wrapper;
 
 public enum Symbol {
 
-	separator(" "), param("--");
+	separator(" "), param("");
 
 	private String symbol;
 
-	private Symbol(String symbol) {
+	Symbol(String symbol) {
 		this.symbol = symbol;
 	}
 

+ 1 - 3
src/main/java/br/eti/mertz/wkhtmltopdf/wrapper/builder/PdfService.java

@@ -6,7 +6,5 @@ import br.eti.mertz.wkhtmltopdf.wrapper.Command;
 
 public interface PdfService {
 	
-	File execute(Command command){
-		
-	}
+	File execute(Command command);
 }

+ 36 - 0
src/tests/java/br/eti/mertz/wkhtmltopdf/wrapper/PdfTest.java

@@ -0,0 +1,36 @@
+package br.eti.mertz.wkhtmltopdf.wrapper;
+
+import org.apache.pdfbox.pdfparser.PDFParser;
+import org.apache.pdfbox.pdmodel.PDDocument;
+import org.apache.pdfbox.util.PDFTextStripper;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.io.ByteArrayInputStream;
+
+import static org.hamcrest.core.StringContains.containsString;
+
+public class PdfTest {
+
+    @Test
+    public void testPdfFromStringTo() throws Exception {
+
+        // GIVEN a html template containing special characters that java stores in utf-16 internally
+        Pdf pdf = new Pdf();
+        pdf.addHtmlInput("<html><head><meta charset=\"utf-8\"></head><h1>Müller</h1></html>");
+
+        // WHEN
+        byte[] pdfBytes =  pdf.getPDF();
+
+        PDFParser parser = new PDFParser(new ByteArrayInputStream(pdfBytes));
+
+        // that is a valid PDF (otherwise an IOException occurs)
+        parser.parse();
+        PDFTextStripper pdfTextStripper = new PDFTextStripper();
+        String pdfText = pdfTextStripper.getText(new PDDocument(parser.getDocument()));
+
+        Assert.assertThat("document should contain the creditorName", pdfText, containsString("Müller"));
+
+
+    }
+}