mirror of
https://github.com/gotenberg/gotenberg.git
synced 2026-08-08 00:22:14 +01:00
Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5a03e17e00 | ||
|
|
417d145b43 | ||
|
|
e5636a2afa | ||
|
|
5291d2d129 | ||
|
|
c6f6a87499 |
@@ -11,7 +11,7 @@ At TheCodingMachine, we build a lot of web applications (intranets, extranets an
|
|||||||
## Features
|
## Features
|
||||||
|
|
||||||
* HTML and Markdown conversions using Google Chrome headless
|
* HTML and Markdown conversions using Google Chrome headless
|
||||||
* Office conversions (.docx, .doc, .odt, .pptx, .ppt, .odp and so on) using [unoconv](https://github.com/dagwieers/unoconv)
|
* Office conversions (.txt, .rtf, .docx, .doc, .odt, .pptx, .ppt, .odp and so on) using [unoconv](https://github.com/dagwieers/unoconv)
|
||||||
* Performance :zap:: Google Chrome and Libreoffice (unoconv) started once in the background thanks to PM2
|
* Performance :zap:: Google Chrome and Libreoffice (unoconv) started once in the background thanks to PM2
|
||||||
* Failure prevention :broken_heart:: PM2 automatically restarts previous processes if they fail
|
* Failure prevention :broken_heart:: PM2 automatically restarts previous processes if they fail
|
||||||
* Assets :package:: send your header, footer, images, fonts, stylesheets and so on for converting your HTML and Markdown to beaufitul PDFs!
|
* Assets :package:: send your header, footer, images, fonts, stylesheets and so on for converting your HTML and Markdown to beaufitul PDFs!
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ LABEL authors="Julien Neuhart <j.neuhart@thecodingmachine.com>"
|
|||||||
|
|
||||||
RUN echo "deb http://httpredir.debian.org/debian/ stretch main contrib non-free" > /etc/apt/sources.list &&\
|
RUN echo "deb http://httpredir.debian.org/debian/ stretch main contrib non-free" > /etc/apt/sources.list &&\
|
||||||
apt-get update &&\
|
apt-get update &&\
|
||||||
apt-get install -y curl wget
|
apt-get install -y curl wget python3-pip
|
||||||
|
|
||||||
# |--------------------------------------------------------------------------
|
# |--------------------------------------------------------------------------
|
||||||
# | PM2
|
# | PM2
|
||||||
@@ -39,7 +39,10 @@ RUN wget -q -O - https://dl.google.com/linux/linux_signing_key.pub | apt-key add
|
|||||||
# | Unoconv
|
# | Unoconv
|
||||||
# |--------------------------------------------------------------------------
|
# |--------------------------------------------------------------------------
|
||||||
# |
|
# |
|
||||||
# | Installs MS fonts and unoconv for Office documents conversions.
|
# | Installs unoconv and LibreOffice for Office documents conversions.
|
||||||
# |
|
# |
|
||||||
|
|
||||||
RUN apt-get -y install ttf-mscorefonts-installer unoconv
|
RUN pip3 install unoconv &&\
|
||||||
|
# https://github.com/nextcloud/docker/issues/380
|
||||||
|
mkdir -p /usr/share/man/man1mkdir -p /usr/share/man/man1 &&\
|
||||||
|
apt-get -y install libreoffice
|
||||||
@@ -5,7 +5,7 @@ title: Introduction
|
|||||||
[Gotenberg](https://github.com/thecodingmachine/gotenberg/) is a Docker-powered stateless API for converting HTML, Markdown and Office documents to PDF.
|
[Gotenberg](https://github.com/thecodingmachine/gotenberg/) is a Docker-powered stateless API for converting HTML, Markdown and Office documents to PDF.
|
||||||
|
|
||||||
* HTML and Markdown conversions using Google Chrome headless
|
* HTML and Markdown conversions using Google Chrome headless
|
||||||
* Office conversions (.docx, .doc, .odt, .pptx, .ppt, .odp and so on) using [unoconv](https://github.com/dagwieers/unoconv)
|
* Office conversions (.txt, .rtf, .docx, .doc, .odt, .pptx, .ppt, .odp and so on) using [unoconv](https://github.com/dagwieers/unoconv)
|
||||||
* Performance: Google Chrome and Libreoffice (unoconv) started once in the background thanks to PM2
|
* Performance: Google Chrome and Libreoffice (unoconv) started once in the background thanks to PM2
|
||||||
* Failure prevention: PM2 automatically restarts previous processes if they fail
|
* Failure prevention: PM2 automatically restarts previous processes if they fail
|
||||||
* Assets: send your header, footer, images, fonts, stylesheets and so on for converting your HTML and Markdown to beaufitul PDFs!
|
* Assets: send your header, footer, images, fonts, stylesheets and so on for converting your HTML and Markdown to beaufitul PDFs!
|
||||||
|
|||||||
@@ -43,9 +43,7 @@ import "github.com/thecodingmachine/gotenberg/pkg"
|
|||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
c := &gotenberg.Client{Hostname: "http://localhost:3000"}
|
c := &gotenberg.Client{Hostname: "http://localhost:3000"}
|
||||||
req := &gotenberg.HTMLRequest{
|
req, _ := gotenberg.NewHTMLRequest("index.html")
|
||||||
IndexFilePath: "index.html",
|
|
||||||
}
|
|
||||||
dest := "result.pdf"
|
dest := "result.pdf"
|
||||||
c.Store(req, dest)
|
c.Store(req, dest)
|
||||||
}
|
}
|
||||||
@@ -119,13 +117,9 @@ import "github.com/thecodingmachine/gotenberg/pkg"
|
|||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
c := &gotenberg.Client{Hostname: "http://localhost:3000"}
|
c := &gotenberg.Client{Hostname: "http://localhost:3000"}
|
||||||
req := &gotenberg.HTMLRequest{
|
req, _ := gotenberg.NewHTMLRequest("index.html")
|
||||||
IndexFilePath: "index.html",
|
req.SetHeader("header.html")
|
||||||
Options: &gotenberg.HTMLOptions{
|
req.SetFooter("footer.html")
|
||||||
HeaderFilePath: "header.html",
|
|
||||||
FooterFilePath: "footer.html",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
dest := "result.pdf"
|
dest := "result.pdf"
|
||||||
c.Store(req, dest)
|
c.Store(req, dest)
|
||||||
}
|
}
|
||||||
@@ -213,14 +207,12 @@ import "github.com/thecodingmachine/gotenberg/pkg"
|
|||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
c := &gotenberg.Client{Hostname: "http://localhost:3000"}
|
c := &gotenberg.Client{Hostname: "http://localhost:3000"}
|
||||||
req := &gotenberg.HTMLRequest{
|
req, _ := gotenberg.NewHTMLRequest("index.html")
|
||||||
IndexFilePath: "index.html",
|
req.SetAssets([]string{
|
||||||
AssetFilePaths: []string{
|
"font.woff",
|
||||||
"style.css",
|
"img.gif",
|
||||||
"img.png",
|
"style.css",
|
||||||
"font.woff",
|
})
|
||||||
},
|
|
||||||
}
|
|
||||||
dest := "result.pdf"
|
dest := "result.pdf"
|
||||||
c.Store(req, dest)
|
c.Store(req, dest)
|
||||||
}
|
}
|
||||||
@@ -279,14 +271,10 @@ import "github.com/thecodingmachine/gotenberg/pkg"
|
|||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
c := &gotenberg.Client{Hostname: "http://localhost:3000"}
|
c := &gotenberg.Client{Hostname: "http://localhost:3000"}
|
||||||
req := &gotenberg.HTMLRequest{
|
req, _ := gotenberg.NewHTMLRequest("index.html")
|
||||||
IndexFilePath: "index.html",
|
req.SetPaperSize(gotenberg.A4)
|
||||||
Options: &gotenberg.HTMLOptions{
|
req.SetMargins(gotenberg.NormalMargins)
|
||||||
PaperSize: gotenberg.A4,
|
req.SetLandscape(true)
|
||||||
PaperMargins: gotenberg.NoMargins,
|
|
||||||
Landscape: true
|
|
||||||
},
|
|
||||||
}
|
|
||||||
dest := "result.pdf"
|
dest := "result.pdf"
|
||||||
c.Store(req, dest)
|
c.Store(req, dest)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,12 +46,7 @@ import "github.com/thecodingmachine/gotenberg/pkg"
|
|||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
c := &gotenberg.Client{Hostname: "http://localhost:3000"}
|
c := &gotenberg.Client{Hostname: "http://localhost:3000"}
|
||||||
req := &gotenberg.MarkdownRequest{
|
req, _ := gotenberg.NewMarkdownRequest("index.html", []string{"file.md"})
|
||||||
IndexFilePath: "index.html",
|
|
||||||
MarkdownFilePaths: []string{
|
|
||||||
"file.md",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
dest := "result.pdf"
|
dest := "result.pdf"
|
||||||
c.Store(req, dest)
|
c.Store(req, dest)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ It accepts `POST` requests with a `multipart/form-data` Content-Type.
|
|||||||
|
|
||||||
You may send one or more Office documents. Following file extensions are accepted:
|
You may send one or more Office documents. Following file extensions are accepted:
|
||||||
|
|
||||||
|
* `.txt`
|
||||||
|
* `.rtf`
|
||||||
* `.doc`
|
* `.doc`
|
||||||
* `.docx`
|
* `.docx`
|
||||||
* `.odt`
|
* `.odt`
|
||||||
@@ -44,12 +46,7 @@ import "github.com/thecodingmachine/gotenberg/pkg"
|
|||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
c := &gotenberg.Client{Hostname: "http://localhost:3000"}
|
c := &gotenberg.Client{Hostname: "http://localhost:3000"}
|
||||||
req := &gotenberg.OfficeRequest{
|
req, _ := gotenberg.NewOfficeRequest([]string{"document.docx", "document2.docx"})
|
||||||
FilePaths: []string{
|
|
||||||
"document.docx",
|
|
||||||
"document2.docx",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
dest := "result.pdf"
|
dest := "result.pdf"
|
||||||
c.Store(req, dest)
|
c.Store(req, dest)
|
||||||
}
|
}
|
||||||
@@ -72,6 +69,62 @@ $dirPath = "/foo";
|
|||||||
$filename = $client->store($request, $dirPath);
|
$filename = $client->store($request, $dirPath);
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Paper size and orientation
|
||||||
|
|
||||||
|
You may also customize the resulting PDF format.
|
||||||
|
|
||||||
|
By default, it will be rendered with `A4` size and `portrait` orientation.
|
||||||
|
|
||||||
|
> Paper size has to be provided in `inches`.
|
||||||
|
> Also, you have to set both `paperWidth` and `paperHeight`.
|
||||||
|
|
||||||
|
### cURL
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ curl --request POST \
|
||||||
|
--url http://localhost:3000/convert/office \
|
||||||
|
--header 'Content-Type: multipart/form-data' \
|
||||||
|
--form files=@document.docx \
|
||||||
|
--form paperWidth=8.27 \
|
||||||
|
--form paperHeight=11.27 \
|
||||||
|
--form landscape=true \
|
||||||
|
> result.pdf
|
||||||
|
```
|
||||||
|
|
||||||
|
### Go
|
||||||
|
|
||||||
|
```golang
|
||||||
|
import "github.com/thecodingmachine/gotenberg/pkg"
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
c := &gotenberg.Client{Hostname: "http://localhost:3000"}
|
||||||
|
req, _ := gotenberg.NewOfficeRequest([]string{"document.docx"})
|
||||||
|
req.SetPaperSize(gotenberg.A4)
|
||||||
|
req.SetLandscape(true)
|
||||||
|
dest := "result.pdf"
|
||||||
|
c.Store(req, dest)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### PHP
|
||||||
|
|
||||||
|
```php
|
||||||
|
use TheCodingMachine\Gotenberg\Client;
|
||||||
|
use TheCodingMachine\Gotenberg\DocumentFactory;
|
||||||
|
use TheCodingMachine\Gotenberg\OfficeRequest;
|
||||||
|
|
||||||
|
$client = new Client('http://localhost:3000', new \Http\Adapter\Guzzle6\Client());
|
||||||
|
$files = [
|
||||||
|
DocumentFactory::makeFromPath('document.docx', 'document.docx'),
|
||||||
|
];
|
||||||
|
$request = new OfficeRequest($files);
|
||||||
|
$request->setPaperSize(Request::A4);
|
||||||
|
$request->setMargins(Request::NO_MARGINS);
|
||||||
|
$request->setLandscape(true);
|
||||||
|
$dirPath = "/foo";
|
||||||
|
$filename = $client->store($request, $dirPath);
|
||||||
|
```
|
||||||
|
|
||||||
## Fonts
|
## Fonts
|
||||||
|
|
||||||
By default, only `ttf-mscorefonts` fonts are installed.
|
By default, only `ttf-mscorefonts` fonts are installed.
|
||||||
|
|||||||
@@ -29,12 +29,7 @@ import "github.com/thecodingmachine/gotenberg/pkg"
|
|||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
c := &gotenberg.Client{Hostname: "http://localhost:3000"}
|
c := &gotenberg.Client{Hostname: "http://localhost:3000"}
|
||||||
req := &gotenberg.MergeRequest{
|
req, _ := gotenberg.NewMergeRequest([]string{"file.pdf", "file2.pdf"})
|
||||||
FilePaths: []string{
|
|
||||||
"file.pdf",
|
|
||||||
"file2.pdf",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
dest := "result.pdf"
|
dest := "result.pdf"
|
||||||
c.Store(req, dest)
|
c.Store(req, dest)
|
||||||
}
|
}
|
||||||
|
|||||||
128
docs/index.html
128
docs/index.html
@@ -71,7 +71,7 @@
|
|||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li>HTML and Markdown conversions using Google Chrome headless</li>
|
<li>HTML and Markdown conversions using Google Chrome headless</li>
|
||||||
<li>Office conversions (.docx, .doc, .odt, .pptx, .ppt, .odp and so on) using <a href="https://github.com/dagwieers/unoconv">unoconv</a></li>
|
<li>Office conversions (.txt, .rtf, .docx, .doc, .odt, .pptx, .ppt, .odp and so on) using <a href="https://github.com/dagwieers/unoconv">unoconv</a></li>
|
||||||
<li>Performance: Google Chrome and Libreoffice (unoconv) started once in the background thanks to PM2</li>
|
<li>Performance: Google Chrome and Libreoffice (unoconv) started once in the background thanks to PM2</li>
|
||||||
<li>Failure prevention: PM2 automatically restarts previous processes if they fail</li>
|
<li>Failure prevention: PM2 automatically restarts previous processes if they fail</li>
|
||||||
<li>Assets: send your header, footer, images, fonts, stylesheets and so on for converting your HTML and Markdown to beaufitul PDFs!</li>
|
<li>Assets: send your header, footer, images, fonts, stylesheets and so on for converting your HTML and Markdown to beaufitul PDFs!</li>
|
||||||
@@ -187,9 +187,7 @@ which will be converted to PDF.</p>
|
|||||||
|
|
||||||
<span class="kd">func</span> <span class="nx">main</span><span class="p">()</span> <span class="p">{</span>
|
<span class="kd">func</span> <span class="nx">main</span><span class="p">()</span> <span class="p">{</span>
|
||||||
<span class="nx">c</span> <span class="o">:=</span> <span class="o">&</span><span class="nx">gotenberg</span><span class="p">.</span><span class="nx">Client</span><span class="p">{</span><span class="nx">Hostname</span><span class="p">:</span> <span class="s">"http://localhost:3000"</span><span class="p">}</span>
|
<span class="nx">c</span> <span class="o">:=</span> <span class="o">&</span><span class="nx">gotenberg</span><span class="p">.</span><span class="nx">Client</span><span class="p">{</span><span class="nx">Hostname</span><span class="p">:</span> <span class="s">"http://localhost:3000"</span><span class="p">}</span>
|
||||||
<span class="nx">req</span> <span class="o">:=</span> <span class="o">&</span><span class="nx">gotenberg</span><span class="p">.</span><span class="nx">HTMLRequest</span><span class="p">{</span>
|
<span class="nx">req</span><span class="p">,</span> <span class="nx">_</span> <span class="o">:=</span> <span class="nx">gotenberg</span><span class="p">.</span><span class="nx">NewHTMLRequest</span><span class="p">(</span><span class="s">"index.html"</span><span class="p">)</span>
|
||||||
<span class="nx">IndexFilePath</span><span class="p">:</span> <span class="s">"index.html"</span><span class="p">,</span>
|
|
||||||
<span class="p">}</span>
|
|
||||||
<span class="nx">dest</span> <span class="o">:=</span> <span class="s">"result.pdf"</span>
|
<span class="nx">dest</span> <span class="o">:=</span> <span class="s">"result.pdf"</span>
|
||||||
<span class="nx">c</span><span class="p">.</span><span class="nx">Store</span><span class="p">(</span><span class="nx">req</span><span class="p">,</span> <span class="nx">dest</span><span class="p">)</span>
|
<span class="nx">c</span><span class="p">.</span><span class="nx">Store</span><span class="p">(</span><span class="nx">req</span><span class="p">,</span> <span class="nx">dest</span><span class="p">)</span>
|
||||||
<span class="p">}</span>
|
<span class="p">}</span>
|
||||||
@@ -271,13 +269,9 @@ Also, <code>footer.html</code> CSS properties override the ones from <code>heade
|
|||||||
|
|
||||||
<span class="kd">func</span> <span class="nx">main</span><span class="p">()</span> <span class="p">{</span>
|
<span class="kd">func</span> <span class="nx">main</span><span class="p">()</span> <span class="p">{</span>
|
||||||
<span class="nx">c</span> <span class="o">:=</span> <span class="o">&</span><span class="nx">gotenberg</span><span class="p">.</span><span class="nx">Client</span><span class="p">{</span><span class="nx">Hostname</span><span class="p">:</span> <span class="s">"http://localhost:3000"</span><span class="p">}</span>
|
<span class="nx">c</span> <span class="o">:=</span> <span class="o">&</span><span class="nx">gotenberg</span><span class="p">.</span><span class="nx">Client</span><span class="p">{</span><span class="nx">Hostname</span><span class="p">:</span> <span class="s">"http://localhost:3000"</span><span class="p">}</span>
|
||||||
<span class="nx">req</span> <span class="o">:=</span> <span class="o">&</span><span class="nx">gotenberg</span><span class="p">.</span><span class="nx">HTMLRequest</span><span class="p">{</span>
|
<span class="nx">req</span><span class="p">,</span> <span class="nx">_</span> <span class="o">:=</span> <span class="nx">gotenberg</span><span class="p">.</span><span class="nx">NewHTMLRequest</span><span class="p">(</span><span class="s">"index.html"</span><span class="p">)</span>
|
||||||
<span class="nx">IndexFilePath</span><span class="p">:</span> <span class="s">"index.html"</span><span class="p">,</span>
|
<span class="nx">req</span><span class="p">.</span><span class="nx">SetHeader</span><span class="p">(</span><span class="s">"header.html"</span><span class="p">)</span>
|
||||||
<span class="nx">Options</span><span class="p">:</span> <span class="o">&</span><span class="nx">gotenberg</span><span class="p">.</span><span class="nx">HTMLOptions</span><span class="p">{</span>
|
<span class="nx">req</span><span class="p">.</span><span class="nx">SetFooter</span><span class="p">(</span><span class="s">"footer.html"</span><span class="p">)</span>
|
||||||
<span class="nx">HeaderFilePath</span><span class="p">:</span> <span class="s">"header.html"</span><span class="p">,</span>
|
|
||||||
<span class="nx">FooterFilePath</span><span class="p">:</span> <span class="s">"footer.html"</span><span class="p">,</span>
|
|
||||||
<span class="p">},</span>
|
|
||||||
<span class="p">}</span>
|
|
||||||
<span class="nx">dest</span> <span class="o">:=</span> <span class="s">"result.pdf"</span>
|
<span class="nx">dest</span> <span class="o">:=</span> <span class="s">"result.pdf"</span>
|
||||||
<span class="nx">c</span><span class="p">.</span><span class="nx">Store</span><span class="p">(</span><span class="nx">req</span><span class="p">,</span> <span class="nx">dest</span><span class="p">)</span>
|
<span class="nx">c</span><span class="p">.</span><span class="nx">Store</span><span class="p">(</span><span class="nx">req</span><span class="p">,</span> <span class="nx">dest</span><span class="p">)</span>
|
||||||
<span class="p">}</span>
|
<span class="p">}</span>
|
||||||
@@ -370,14 +364,12 @@ see to the <a href="#office.fonts">fonts section</a>.</p>
|
|||||||
|
|
||||||
<span class="kd">func</span> <span class="nx">main</span><span class="p">()</span> <span class="p">{</span>
|
<span class="kd">func</span> <span class="nx">main</span><span class="p">()</span> <span class="p">{</span>
|
||||||
<span class="nx">c</span> <span class="o">:=</span> <span class="o">&</span><span class="nx">gotenberg</span><span class="p">.</span><span class="nx">Client</span><span class="p">{</span><span class="nx">Hostname</span><span class="p">:</span> <span class="s">"http://localhost:3000"</span><span class="p">}</span>
|
<span class="nx">c</span> <span class="o">:=</span> <span class="o">&</span><span class="nx">gotenberg</span><span class="p">.</span><span class="nx">Client</span><span class="p">{</span><span class="nx">Hostname</span><span class="p">:</span> <span class="s">"http://localhost:3000"</span><span class="p">}</span>
|
||||||
<span class="nx">req</span> <span class="o">:=</span> <span class="o">&</span><span class="nx">gotenberg</span><span class="p">.</span><span class="nx">HTMLRequest</span><span class="p">{</span>
|
<span class="nx">req</span><span class="p">,</span> <span class="nx">_</span> <span class="o">:=</span> <span class="nx">gotenberg</span><span class="p">.</span><span class="nx">NewHTMLRequest</span><span class="p">(</span><span class="s">"index.html"</span><span class="p">)</span>
|
||||||
<span class="nx">IndexFilePath</span><span class="p">:</span> <span class="s">"index.html"</span><span class="p">,</span>
|
<span class="nx">req</span><span class="p">.</span><span class="nx">SetAssets</span><span class="p">([]</span><span class="kt">string</span><span class="p">{</span>
|
||||||
<span class="nx">AssetFilePaths</span><span class="p">:</span> <span class="p">[]</span><span class="kt">string</span><span class="p">{</span>
|
<span class="s">"font.woff"</span><span class="p">,</span>
|
||||||
<span class="s">"style.css"</span><span class="p">,</span>
|
<span class="s">"img.gif"</span><span class="p">,</span>
|
||||||
<span class="s">"img.png"</span><span class="p">,</span>
|
<span class="s">"style.css"</span><span class="p">,</span>
|
||||||
<span class="s">"font.woff"</span><span class="p">,</span>
|
<span class="p">})</span>
|
||||||
<span class="p">},</span>
|
|
||||||
<span class="p">}</span>
|
|
||||||
<span class="nx">dest</span> <span class="o">:=</span> <span class="s">"result.pdf"</span>
|
<span class="nx">dest</span> <span class="o">:=</span> <span class="s">"result.pdf"</span>
|
||||||
<span class="nx">c</span><span class="p">.</span><span class="nx">Store</span><span class="p">(</span><span class="nx">req</span><span class="p">,</span> <span class="nx">dest</span><span class="p">)</span>
|
<span class="nx">c</span><span class="p">.</span><span class="nx">Store</span><span class="p">(</span><span class="nx">req</span><span class="p">,</span> <span class="nx">dest</span><span class="p">)</span>
|
||||||
<span class="p">}</span>
|
<span class="p">}</span>
|
||||||
@@ -443,14 +435,10 @@ Also, you have to set both <code>paperWidth</code> and <code>paperHeight</code>.
|
|||||||
|
|
||||||
<span class="kd">func</span> <span class="nx">main</span><span class="p">()</span> <span class="p">{</span>
|
<span class="kd">func</span> <span class="nx">main</span><span class="p">()</span> <span class="p">{</span>
|
||||||
<span class="nx">c</span> <span class="o">:=</span> <span class="o">&</span><span class="nx">gotenberg</span><span class="p">.</span><span class="nx">Client</span><span class="p">{</span><span class="nx">Hostname</span><span class="p">:</span> <span class="s">"http://localhost:3000"</span><span class="p">}</span>
|
<span class="nx">c</span> <span class="o">:=</span> <span class="o">&</span><span class="nx">gotenberg</span><span class="p">.</span><span class="nx">Client</span><span class="p">{</span><span class="nx">Hostname</span><span class="p">:</span> <span class="s">"http://localhost:3000"</span><span class="p">}</span>
|
||||||
<span class="nx">req</span> <span class="o">:=</span> <span class="o">&</span><span class="nx">gotenberg</span><span class="p">.</span><span class="nx">HTMLRequest</span><span class="p">{</span>
|
<span class="nx">req</span><span class="p">,</span> <span class="nx">_</span> <span class="o">:=</span> <span class="nx">gotenberg</span><span class="p">.</span><span class="nx">NewHTMLRequest</span><span class="p">(</span><span class="s">"index.html"</span><span class="p">)</span>
|
||||||
<span class="nx">IndexFilePath</span><span class="p">:</span> <span class="s">"index.html"</span><span class="p">,</span>
|
<span class="nx">req</span><span class="p">.</span><span class="nx">SetPaperSize</span><span class="p">(</span><span class="nx">gotenberg</span><span class="p">.</span><span class="nx">A4</span><span class="p">)</span>
|
||||||
<span class="nx">Options</span><span class="p">:</span> <span class="o">&</span><span class="nx">gotenberg</span><span class="p">.</span><span class="nx">HTMLOptions</span><span class="p">{</span>
|
<span class="nx">req</span><span class="p">.</span><span class="nx">SetMargins</span><span class="p">(</span><span class="nx">gotenberg</span><span class="p">.</span><span class="nx">NormalMargins</span><span class="p">)</span>
|
||||||
<span class="nx">PaperSize</span><span class="p">:</span> <span class="nx">gotenberg</span><span class="p">.</span><span class="nx">A4</span><span class="p">,</span>
|
<span class="nx">req</span><span class="p">.</span><span class="nx">SetLandscape</span><span class="p">(</span><span class="kc">true</span><span class="p">)</span>
|
||||||
<span class="nx">PaperMargins</span><span class="p">:</span> <span class="nx">gotenberg</span><span class="p">.</span><span class="nx">NoMargins</span><span class="p">,</span>
|
|
||||||
<span class="nx">Landscape</span><span class="p">:</span> <span class="kc">true</span>
|
|
||||||
<span class="p">},</span>
|
|
||||||
<span class="p">}</span>
|
|
||||||
<span class="nx">dest</span> <span class="o">:=</span> <span class="s">"result.pdf"</span>
|
<span class="nx">dest</span> <span class="o">:=</span> <span class="s">"result.pdf"</span>
|
||||||
<span class="nx">c</span><span class="p">.</span><span class="nx">Store</span><span class="p">(</span><span class="nx">req</span><span class="p">,</span> <span class="nx">dest</span><span class="p">)</span>
|
<span class="nx">c</span><span class="p">.</span><span class="nx">Store</span><span class="p">(</span><span class="nx">req</span><span class="p">,</span> <span class="nx">dest</span><span class="p">)</span>
|
||||||
<span class="p">}</span>
|
<span class="p">}</span>
|
||||||
@@ -528,12 +516,7 @@ in the file <code>index.html</code>. This function will convert a given markdown
|
|||||||
|
|
||||||
<span class="kd">func</span> <span class="nx">main</span><span class="p">()</span> <span class="p">{</span>
|
<span class="kd">func</span> <span class="nx">main</span><span class="p">()</span> <span class="p">{</span>
|
||||||
<span class="nx">c</span> <span class="o">:=</span> <span class="o">&</span><span class="nx">gotenberg</span><span class="p">.</span><span class="nx">Client</span><span class="p">{</span><span class="nx">Hostname</span><span class="p">:</span> <span class="s">"http://localhost:3000"</span><span class="p">}</span>
|
<span class="nx">c</span> <span class="o">:=</span> <span class="o">&</span><span class="nx">gotenberg</span><span class="p">.</span><span class="nx">Client</span><span class="p">{</span><span class="nx">Hostname</span><span class="p">:</span> <span class="s">"http://localhost:3000"</span><span class="p">}</span>
|
||||||
<span class="nx">req</span> <span class="o">:=</span> <span class="o">&</span><span class="nx">gotenberg</span><span class="p">.</span><span class="nx">MarkdownRequest</span><span class="p">{</span>
|
<span class="nx">req</span><span class="p">,</span> <span class="nx">_</span> <span class="o">:=</span> <span class="nx">gotenberg</span><span class="p">.</span><span class="nx">NewMarkdownRequest</span><span class="p">(</span><span class="s">"index.html"</span><span class="p">,</span> <span class="p">[]</span><span class="kt">string</span><span class="p">{</span><span class="s">"file.md"</span><span class="p">})</span>
|
||||||
<span class="nx">IndexFilePath</span><span class="p">:</span> <span class="s">"index.html"</span><span class="p">,</span>
|
|
||||||
<span class="nx">MarkdownFilePaths</span><span class="p">:</span> <span class="p">[]</span><span class="kt">string</span><span class="p">{</span>
|
|
||||||
<span class="s">"file.md"</span><span class="p">,</span>
|
|
||||||
<span class="p">},</span>
|
|
||||||
<span class="p">}</span>
|
|
||||||
<span class="nx">dest</span> <span class="o">:=</span> <span class="s">"result.pdf"</span>
|
<span class="nx">dest</span> <span class="o">:=</span> <span class="s">"result.pdf"</span>
|
||||||
<span class="nx">c</span><span class="p">.</span><span class="nx">Store</span><span class="p">(</span><span class="nx">req</span><span class="p">,</span> <span class="nx">dest</span><span class="p">)</span>
|
<span class="nx">c</span><span class="p">.</span><span class="nx">Store</span><span class="p">(</span><span class="nx">req</span><span class="p">,</span> <span class="nx">dest</span><span class="p">)</span>
|
||||||
<span class="p">}</span>
|
<span class="p">}</span>
|
||||||
@@ -574,6 +557,8 @@ in the file <code>index.html</code>. This function will convert a given markdown
|
|||||||
<p>You may send one or more Office documents. Following file extensions are accepted:</p>
|
<p>You may send one or more Office documents. Following file extensions are accepted:</p>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
|
<li><code>.txt</code></li>
|
||||||
|
<li><code>.rtf</code></li>
|
||||||
<li><code>.doc</code></li>
|
<li><code>.doc</code></li>
|
||||||
<li><code>.docx</code></li>
|
<li><code>.docx</code></li>
|
||||||
<li><code>.odt</code></li>
|
<li><code>.odt</code></li>
|
||||||
@@ -613,12 +598,7 @@ See the <a href="#scalability">scalability section</a> to find how to mitigate t
|
|||||||
|
|
||||||
<span class="kd">func</span> <span class="nx">main</span><span class="p">()</span> <span class="p">{</span>
|
<span class="kd">func</span> <span class="nx">main</span><span class="p">()</span> <span class="p">{</span>
|
||||||
<span class="nx">c</span> <span class="o">:=</span> <span class="o">&</span><span class="nx">gotenberg</span><span class="p">.</span><span class="nx">Client</span><span class="p">{</span><span class="nx">Hostname</span><span class="p">:</span> <span class="s">"http://localhost:3000"</span><span class="p">}</span>
|
<span class="nx">c</span> <span class="o">:=</span> <span class="o">&</span><span class="nx">gotenberg</span><span class="p">.</span><span class="nx">Client</span><span class="p">{</span><span class="nx">Hostname</span><span class="p">:</span> <span class="s">"http://localhost:3000"</span><span class="p">}</span>
|
||||||
<span class="nx">req</span> <span class="o">:=</span> <span class="o">&</span><span class="nx">gotenberg</span><span class="p">.</span><span class="nx">OfficeRequest</span><span class="p">{</span>
|
<span class="nx">req</span><span class="p">,</span> <span class="nx">_</span> <span class="o">:=</span> <span class="nx">gotenberg</span><span class="p">.</span><span class="nx">NewOfficeRequest</span><span class="p">([]</span><span class="kt">string</span><span class="p">{</span><span class="s">"document.docx"</span><span class="p">,</span> <span class="s">"document2.docx"</span><span class="p">})</span>
|
||||||
<span class="nx">FilePaths</span><span class="p">:</span> <span class="p">[]</span><span class="kt">string</span><span class="p">{</span>
|
|
||||||
<span class="s">"document.docx"</span><span class="p">,</span>
|
|
||||||
<span class="s">"document2.docx"</span><span class="p">,</span>
|
|
||||||
<span class="p">},</span>
|
|
||||||
<span class="p">}</span>
|
|
||||||
<span class="nx">dest</span> <span class="o">:=</span> <span class="s">"result.pdf"</span>
|
<span class="nx">dest</span> <span class="o">:=</span> <span class="s">"result.pdf"</span>
|
||||||
<span class="nx">c</span><span class="p">.</span><span class="nx">Store</span><span class="p">(</span><span class="nx">req</span><span class="p">,</span> <span class="nx">dest</span><span class="p">)</span>
|
<span class="nx">c</span><span class="p">.</span><span class="nx">Store</span><span class="p">(</span><span class="nx">req</span><span class="p">,</span> <span class="nx">dest</span><span class="p">)</span>
|
||||||
<span class="p">}</span>
|
<span class="p">}</span>
|
||||||
@@ -642,6 +622,69 @@ See the <a href="#scalability">scalability section</a> to find how to mitigate t
|
|||||||
</span><span class="x">$filename = $client->store($request, $dirPath);
|
</span><span class="x">$filename = $client->store($request, $dirPath);
|
||||||
</span><span class="x"></span></pre>
|
</span><span class="x"></span></pre>
|
||||||
|
|
||||||
|
<h2 class="Heading"><a class="Anchor" aria-hidden="true" id="office.paper_size_and_orientation" href="#office.paper_size_and_orientation">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-link"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"></path><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"></path></svg>
|
||||||
|
</a>Paper size and orientation</h2>
|
||||||
|
|
||||||
|
<p>You may also customize the resulting PDF format.</p>
|
||||||
|
|
||||||
|
<p>By default, it will be rendered with <code>A4</code> size and <code>portrait</code> orientation.</p>
|
||||||
|
|
||||||
|
<blockquote>
|
||||||
|
<p>Paper size has to be provided in <code>inches</code>.
|
||||||
|
Also, you have to set both <code>paperWidth</code> and <code>paperHeight</code>.</p>
|
||||||
|
</blockquote>
|
||||||
|
|
||||||
|
<h3 class="Heading"><a class="Anchor" aria-hidden="true" id="office.paper_size_and_orientation.c_url" href="#office.paper_size_and_orientation.c_url">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-link"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"></path><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"></path></svg>
|
||||||
|
</a>cURL</h3>
|
||||||
|
|
||||||
|
<pre class="chroma">$ curl --request POST <span class="se">\
|
||||||
|
</span><span class="se"></span> --url http://localhost:3000/convert/office <span class="se">\
|
||||||
|
</span><span class="se"></span> --header <span class="s1">'Content-Type: multipart/form-data'</span> <span class="se">\
|
||||||
|
</span><span class="se"></span> --form <span class="nv">files</span><span class="o">=</span>@document.docx <span class="se">\
|
||||||
|
</span><span class="se"></span> --form <span class="nv">paperWidth</span><span class="o">=</span><span class="m">8</span>.27 <span class="se">\
|
||||||
|
</span><span class="se"></span> --form <span class="nv">paperHeight</span><span class="o">=</span><span class="m">11</span>.27 <span class="se">\
|
||||||
|
</span><span class="se"></span> --form <span class="nv">landscape</span><span class="o">=</span><span class="nb">true</span> <span class="se">\
|
||||||
|
</span><span class="se"></span> > result.pdf
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<h3 class="Heading"><a class="Anchor" aria-hidden="true" id="office.paper_size_and_orientation.go" href="#office.paper_size_and_orientation.go">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-link"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"></path><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"></path></svg>
|
||||||
|
</a>Go</h3>
|
||||||
|
|
||||||
|
<pre class="chroma"><span class="kn">import</span> <span class="s">"github.com/thecodingmachine/gotenberg/pkg"</span>
|
||||||
|
|
||||||
|
<span class="kd">func</span> <span class="nx">main</span><span class="p">()</span> <span class="p">{</span>
|
||||||
|
<span class="nx">c</span> <span class="o">:=</span> <span class="o">&</span><span class="nx">gotenberg</span><span class="p">.</span><span class="nx">Client</span><span class="p">{</span><span class="nx">Hostname</span><span class="p">:</span> <span class="s">"http://localhost:3000"</span><span class="p">}</span>
|
||||||
|
<span class="nx">req</span><span class="p">,</span> <span class="nx">_</span> <span class="o">:=</span> <span class="nx">gotenberg</span><span class="p">.</span><span class="nx">NewOfficeRequest</span><span class="p">([]</span><span class="kt">string</span><span class="p">{</span><span class="s">"document.docx"</span><span class="p">})</span>
|
||||||
|
<span class="nx">req</span><span class="p">.</span><span class="nx">SetPaperSize</span><span class="p">(</span><span class="nx">gotenberg</span><span class="p">.</span><span class="nx">A4</span><span class="p">)</span>
|
||||||
|
<span class="nx">req</span><span class="p">.</span><span class="nx">SetLandscape</span><span class="p">(</span><span class="kc">true</span><span class="p">)</span>
|
||||||
|
<span class="nx">dest</span> <span class="o">:=</span> <span class="s">"result.pdf"</span>
|
||||||
|
<span class="nx">c</span><span class="p">.</span><span class="nx">Store</span><span class="p">(</span><span class="nx">req</span><span class="p">,</span> <span class="nx">dest</span><span class="p">)</span>
|
||||||
|
<span class="p">}</span>
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<h3 class="Heading"><a class="Anchor" aria-hidden="true" id="office.paper_size_and_orientation.php" href="#office.paper_size_and_orientation.php">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-link"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"></path><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"></path></svg>
|
||||||
|
</a>PHP</h3>
|
||||||
|
|
||||||
|
<pre class="chroma"><span class="x">use TheCodingMachine\Gotenberg\Client;
|
||||||
|
</span><span class="x">use TheCodingMachine\Gotenberg\DocumentFactory;
|
||||||
|
</span><span class="x">use TheCodingMachine\Gotenberg\OfficeRequest;
|
||||||
|
</span><span class="x">
|
||||||
|
</span><span class="x">$client = new Client('http://localhost:3000', new \Http\Adapter\Guzzle6\Client());
|
||||||
|
</span><span class="x">$files = [
|
||||||
|
</span><span class="x"> DocumentFactory::makeFromPath('document.docx', 'document.docx'),
|
||||||
|
</span><span class="x">];
|
||||||
|
</span><span class="x">$request = new OfficeRequest($files);
|
||||||
|
</span><span class="x">$request->setPaperSize(Request::A4);
|
||||||
|
</span><span class="x">$request->setMargins(Request::NO_MARGINS);
|
||||||
|
</span><span class="x">$request->setLandscape(true);
|
||||||
|
</span><span class="x">$dirPath = "/foo";
|
||||||
|
</span><span class="x">$filename = $client->store($request, $dirPath);
|
||||||
|
</span><span class="x"></span></pre>
|
||||||
|
|
||||||
<h2 class="Heading"><a class="Anchor" aria-hidden="true" id="office.fonts" href="#office.fonts">
|
<h2 class="Heading"><a class="Anchor" aria-hidden="true" id="office.fonts" href="#office.fonts">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-link"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"></path><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"></path></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-link"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"></path><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"></path></svg>
|
||||||
</a>Fonts</h2>
|
</a>Fonts</h2>
|
||||||
@@ -692,12 +735,7 @@ will merge them and return the resulting PDF file.</p>
|
|||||||
|
|
||||||
<span class="kd">func</span> <span class="nx">main</span><span class="p">()</span> <span class="p">{</span>
|
<span class="kd">func</span> <span class="nx">main</span><span class="p">()</span> <span class="p">{</span>
|
||||||
<span class="nx">c</span> <span class="o">:=</span> <span class="o">&</span><span class="nx">gotenberg</span><span class="p">.</span><span class="nx">Client</span><span class="p">{</span><span class="nx">Hostname</span><span class="p">:</span> <span class="s">"http://localhost:3000"</span><span class="p">}</span>
|
<span class="nx">c</span> <span class="o">:=</span> <span class="o">&</span><span class="nx">gotenberg</span><span class="p">.</span><span class="nx">Client</span><span class="p">{</span><span class="nx">Hostname</span><span class="p">:</span> <span class="s">"http://localhost:3000"</span><span class="p">}</span>
|
||||||
<span class="nx">req</span> <span class="o">:=</span> <span class="o">&</span><span class="nx">gotenberg</span><span class="p">.</span><span class="nx">MergeRequest</span><span class="p">{</span>
|
<span class="nx">req</span><span class="p">,</span> <span class="nx">_</span> <span class="o">:=</span> <span class="nx">gotenberg</span><span class="p">.</span><span class="nx">NewMergeRequest</span><span class="p">([]</span><span class="kt">string</span><span class="p">{</span><span class="s">"file.pdf"</span><span class="p">,</span> <span class="s">"file2.pdf"</span><span class="p">})</span>
|
||||||
<span class="nx">FilePaths</span><span class="p">:</span> <span class="p">[]</span><span class="kt">string</span><span class="p">{</span>
|
|
||||||
<span class="s">"file.pdf"</span><span class="p">,</span>
|
|
||||||
<span class="s">"file2.pdf"</span><span class="p">,</span>
|
|
||||||
<span class="p">},</span>
|
|
||||||
<span class="p">}</span>
|
|
||||||
<span class="nx">dest</span> <span class="o">:=</span> <span class="s">"result.pdf"</span>
|
<span class="nx">dest</span> <span class="o">:=</span> <span class="s">"result.pdf"</span>
|
||||||
<span class="nx">c</span><span class="p">.</span><span class="nx">Store</span><span class="p">(</span><span class="nx">req</span><span class="p">,</span> <span class="nx">dest</span><span class="p">)</span>
|
<span class="nx">c</span><span class="p">.</span><span class="nx">Store</span><span class="p">(</span><span class="nx">req</span><span class="p">,</span> <span class="nx">dest</span><span class="p">)</span>
|
||||||
<span class="p">}</span>
|
<span class="p">}</span>
|
||||||
|
|||||||
2
go.mod
2
go.mod
@@ -4,7 +4,7 @@ require (
|
|||||||
github.com/derekparker/delve v1.1.0
|
github.com/derekparker/delve v1.1.0
|
||||||
github.com/google/go-cmp v0.2.0 // indirect
|
github.com/google/go-cmp v0.2.0 // indirect
|
||||||
github.com/gorilla/websocket v1.4.0 // indirect
|
github.com/gorilla/websocket v1.4.0 // indirect
|
||||||
github.com/hhrutter/pdfcpu v0.1.18
|
github.com/hhrutter/pdfcpu v0.1.19
|
||||||
github.com/labstack/echo v0.0.0-20181123063703-c7eb8da9ec73
|
github.com/labstack/echo v0.0.0-20181123063703-c7eb8da9ec73
|
||||||
github.com/labstack/gommon v0.2.8
|
github.com/labstack/gommon v0.2.8
|
||||||
github.com/mafredri/cdp v0.20.0
|
github.com/mafredri/cdp v0.20.0
|
||||||
|
|||||||
2
go.sum
2
go.sum
@@ -10,6 +10,8 @@ github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH
|
|||||||
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||||
github.com/hhrutter/pdfcpu v0.1.18 h1:GX3d6tZxmQlmB5X9VUyOtx7+HZZpR+8ISLqBineP6dc=
|
github.com/hhrutter/pdfcpu v0.1.18 h1:GX3d6tZxmQlmB5X9VUyOtx7+HZZpR+8ISLqBineP6dc=
|
||||||
github.com/hhrutter/pdfcpu v0.1.18/go.mod h1:iaCmXGnOXPIvoGLELZZc4m/GpIopVsvLQ00thrbu8LU=
|
github.com/hhrutter/pdfcpu v0.1.18/go.mod h1:iaCmXGnOXPIvoGLELZZc4m/GpIopVsvLQ00thrbu8LU=
|
||||||
|
github.com/hhrutter/pdfcpu v0.1.19 h1:J6GjNFDPjurQWallPW9gmz3CcNqBfvgB7Dad9T3e8Hc=
|
||||||
|
github.com/hhrutter/pdfcpu v0.1.19/go.mod h1:iaCmXGnOXPIvoGLELZZc4m/GpIopVsvLQ00thrbu8LU=
|
||||||
github.com/labstack/echo v0.0.0-20181123063703-c7eb8da9ec73 h1:oQvA3Xy8274W5Ldgo6Nogy4lX8XO5AaIBsjF5Ggk0IU=
|
github.com/labstack/echo v0.0.0-20181123063703-c7eb8da9ec73 h1:oQvA3Xy8274W5Ldgo6Nogy4lX8XO5AaIBsjF5Ggk0IU=
|
||||||
github.com/labstack/echo v0.0.0-20181123063703-c7eb8da9ec73/go.mod h1:rS0D1UPvC8/3sXjhSwEq+K1olh7ipbDhjDWATN2KSgA=
|
github.com/labstack/echo v0.0.0-20181123063703-c7eb8da9ec73/go.mod h1:rS0D1UPvC8/3sXjhSwEq+K1olh7ipbDhjDWATN2KSgA=
|
||||||
github.com/labstack/echo v3.3.5+incompatible h1:9PfxPUmasKzeJor9uQTaXLT6WUG/r+vSTmvXxvv3JO4=
|
github.com/labstack/echo v3.3.5+incompatible h1:9PfxPUmasKzeJor9uQTaXLT6WUG/r+vSTmvXxvv3JO4=
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var officeExts = []string{
|
var officeExts = []string{
|
||||||
|
".txt",
|
||||||
|
".rtf",
|
||||||
".doc",
|
".doc",
|
||||||
".docx",
|
".docx",
|
||||||
".odt",
|
".odt",
|
||||||
@@ -37,5 +39,16 @@ func convertOffice(c echo.Context) error {
|
|||||||
return errors.New("no suitable office documents to convert")
|
return errors.New("no suitable office documents to convert")
|
||||||
}
|
}
|
||||||
p := &printer.Office{Context: ctx, FilePaths: fpaths}
|
p := &printer.Office{Context: ctx, FilePaths: fpaths}
|
||||||
|
paperSize, err := r.paperSize()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
p.PaperWidth = paperSize[0]
|
||||||
|
p.PaperHeight = paperSize[1]
|
||||||
|
landscape, err := r.landscape()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
p.Landscape = landscape
|
||||||
return print(c, p, r)
|
return print(c, p, r)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"strconv"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/thecodingmachine/gotenberg/internal/pkg/rand"
|
"github.com/thecodingmachine/gotenberg/internal/pkg/rand"
|
||||||
@@ -16,8 +17,11 @@ var mu sync.Mutex
|
|||||||
|
|
||||||
// Office facilitates Office documents to PDF conversion.
|
// Office facilitates Office documents to PDF conversion.
|
||||||
type Office struct {
|
type Office struct {
|
||||||
Context context.Context
|
Context context.Context
|
||||||
FilePaths []string
|
FilePaths []string
|
||||||
|
PaperWidth float64
|
||||||
|
PaperHeight float64
|
||||||
|
Landscape bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// Print converts Office documents to PDF.
|
// Print converts Office documents to PDF.
|
||||||
@@ -32,14 +36,24 @@ func (o *Office) Print(destination string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
tmpDest := fmt.Sprintf("%s/%s.pdf", dirPath, baseFilename)
|
tmpDest := fmt.Sprintf("%s/%s.pdf", dirPath, baseFilename)
|
||||||
|
paperSize, err := unoconvPaperSize(o.PaperWidth, o.PaperHeight)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
cmdArgs := []string{
|
||||||
|
"--format",
|
||||||
|
"pdf",
|
||||||
|
"--printer",
|
||||||
|
paperSize,
|
||||||
|
}
|
||||||
|
if o.Landscape {
|
||||||
|
cmdArgs = append(cmdArgs, "--printer", "PaperOrientation=landscape")
|
||||||
|
}
|
||||||
|
cmdArgs = append(cmdArgs, "--output", tmpDest, fpath)
|
||||||
cmd := exec.CommandContext(
|
cmd := exec.CommandContext(
|
||||||
o.Context,
|
o.Context,
|
||||||
"unoconv",
|
"unoconv",
|
||||||
"--format",
|
cmdArgs...,
|
||||||
"pdf",
|
|
||||||
"--output",
|
|
||||||
tmpDest,
|
|
||||||
fpath,
|
|
||||||
)
|
)
|
||||||
_, err = cmd.Output()
|
_, err = cmd.Output()
|
||||||
if o.Context.Err() == context.DeadlineExceeded {
|
if o.Context.Err() == context.DeadlineExceeded {
|
||||||
@@ -56,6 +70,18 @@ func (o *Office) Print(destination string) error {
|
|||||||
return Merge(fpaths, destination)
|
return Merge(fpaths, destination)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func unoconvPaperSize(paperWidth, paperHeight float64) (string, error) {
|
||||||
|
width, err := strconv.Atoi(fmt.Sprintf("%.0f", paperWidth*25.4))
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("%0.f: converting width to millimiter: %v", paperWidth, err)
|
||||||
|
}
|
||||||
|
height, err := strconv.Atoi(fmt.Sprintf("%.0f", paperHeight*25.4))
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("%0.f: converting height to millimiter: %v", paperHeight, err)
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("PaperSize=%dx%d", width, height), nil
|
||||||
|
}
|
||||||
|
|
||||||
// Compile-time checks to ensure type implements desired interfaces.
|
// Compile-time checks to ensure type implements desired interfaces.
|
||||||
var (
|
var (
|
||||||
_ = Printer(new(Office))
|
_ = Printer(new(Office))
|
||||||
|
|||||||
@@ -20,6 +20,8 @@ func TestOffice(t *testing.T) {
|
|||||||
Context: ctx,
|
Context: ctx,
|
||||||
FilePaths: []string{
|
FilePaths: []string{
|
||||||
fmt.Sprintf("%s/%s", dirPath, "document.docx"),
|
fmt.Sprintf("%s/%s", dirPath, "document.docx"),
|
||||||
|
fmt.Sprintf("%s/%s", dirPath, "document.txt"),
|
||||||
|
fmt.Sprintf("%s/%s", dirPath, "document.rtf"),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
dst := fmt.Sprintf("%s/%s", dirPath, "foo.pdf")
|
dst := fmt.Sprintf("%s/%s", dirPath, "foo.pdf")
|
||||||
|
|||||||
@@ -5,9 +5,16 @@ import (
|
|||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
|
||||||
pdfcpuAPI "github.com/hhrutter/pdfcpu/pkg/api"
|
pdfcpuAPI "github.com/hhrutter/pdfcpu/pkg/api"
|
||||||
|
pdfcpuLog "github.com/hhrutter/pdfcpu/pkg/log"
|
||||||
pdfcpuConfig "github.com/hhrutter/pdfcpu/pkg/pdfcpu"
|
pdfcpuConfig "github.com/hhrutter/pdfcpu/pkg/pdfcpu"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
// disable loggers when merging
|
||||||
|
// PDFs.
|
||||||
|
pdfcpuLog.DisableLoggers()
|
||||||
|
}
|
||||||
|
|
||||||
// Printer is a type that can create a PDF file from a source.
|
// Printer is a type that can create a PDF file from a source.
|
||||||
// The source is defined in the underlying implementation.
|
// The source is defined in the underlying implementation.
|
||||||
type Printer interface {
|
type Printer interface {
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ func TestMerge(t *testing.T) {
|
|||||||
err := Merge(
|
err := Merge(
|
||||||
[]string{
|
[]string{
|
||||||
fmt.Sprintf("%s/%s", dirPath, "gotenberg.pdf"),
|
fmt.Sprintf("%s/%s", dirPath, "gotenberg.pdf"),
|
||||||
fmt.Sprintf("%s/%s", dirPath, "gotenberg.pdf"),
|
fmt.Sprintf("%s/%s", dirPath, "gotenberg_bis.pdf"),
|
||||||
},
|
},
|
||||||
dst,
|
dst,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -16,19 +16,17 @@ import "github.com/thecodingmachine/gotenberg/pkg"
|
|||||||
func main() {
|
func main() {
|
||||||
// HTML conversion example.
|
// HTML conversion example.
|
||||||
c := &gotenberg.Client{Hostname: "http://localhost:3000"}
|
c := &gotenberg.Client{Hostname: "http://localhost:3000"}
|
||||||
req := &gotenberg.HTMLRequest{
|
req, _ := gotenberg.NewHTMLRequest("index.html")
|
||||||
IndexFilePath: "index.html",
|
req.SetHeader("header.html")
|
||||||
AssetFilePaths: []string{
|
req.SetFooter("footer.html")
|
||||||
"style.css",
|
req.SetAssets([]string{
|
||||||
"img.png",
|
"font.woff",
|
||||||
},
|
"img.gif",
|
||||||
Options: &gotenberg.HTMLOptions{
|
"style.css",
|
||||||
HeaderFilePath: "header.html",
|
})
|
||||||
FooterFilePath: "footer.html",
|
req.SetPaperSize(A4)
|
||||||
PaperSize: gotenberg.A4,
|
req.SetMargins(NormalMargins)
|
||||||
PaperMargins: gotenberg.NormalMargins,
|
req.SetLandscape(false)
|
||||||
},
|
|
||||||
}
|
|
||||||
dest := "foo.pdf"
|
dest := "foo.pdf"
|
||||||
c.Store(req, dest)
|
c.Store(req, dest)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,18 +59,35 @@ type Client struct {
|
|||||||
// form values and form files to
|
// form values and form files to
|
||||||
// the Gotenberg API.
|
// the Gotenberg API.
|
||||||
type Request interface {
|
type Request interface {
|
||||||
validate() error
|
SetWebhookURL(webhookURL string)
|
||||||
getPostURL() string
|
getPostURL() string
|
||||||
getFormValues() map[string]string
|
getFormValues() map[string]string
|
||||||
getFormFiles() map[string]string
|
getFormFiles() map[string]string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ChromeRequest is a type for sending
|
||||||
|
// conversion requests which will be
|
||||||
|
// handle by Google Chrome.
|
||||||
|
type ChromeRequest interface {
|
||||||
|
SetHeader(fpath string) error
|
||||||
|
SetFooter(fpath string) error
|
||||||
|
SetAssets(fpaths []string) error
|
||||||
|
SetPaperSize(size [2]float64)
|
||||||
|
SetMargins(margins [4]float64)
|
||||||
|
SetLandscape(isLandscape bool)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnoconvRequest is a type for sending
|
||||||
|
// conversion requests which will be
|
||||||
|
// handle by unoconv.
|
||||||
|
type UnoconvRequest interface {
|
||||||
|
SetPaperSize(size [2]float64)
|
||||||
|
SetLandscape(landscape bool)
|
||||||
|
}
|
||||||
|
|
||||||
// Post sends a request to the Gotenberg API
|
// Post sends a request to the Gotenberg API
|
||||||
// and returns the response.
|
// and returns the response.
|
||||||
func (c *Client) Post(req Request) (*http.Response, error) {
|
func (c *Client) Post(req Request) (*http.Response, error) {
|
||||||
if err := req.validate(); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
body, contentType, err := multipartForm(req)
|
body, contentType, err := multipartForm(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|||||||
27
pkg/doc.go
27
pkg/doc.go
@@ -2,30 +2,7 @@
|
|||||||
Package gotenberg is a Go client for
|
Package gotenberg is a Go client for
|
||||||
interacting with a Gotenberg API.
|
interacting with a Gotenberg API.
|
||||||
|
|
||||||
For instance, if you want to convert HTML:
|
For more complete usages, head to the documentation:
|
||||||
|
https://thecodingmachine.gotenberg.github.io.
|
||||||
import "github.com/thecodingmachine/gotenberg/pkg"
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
// HTML conversion example.
|
|
||||||
c := &gotenberg.Client{Hostname: "http://localhost:3000"}
|
|
||||||
req := &gotenberg.HTMLRequest{
|
|
||||||
IndexFilePath: "index.html",
|
|
||||||
AssetFilePaths: []string{
|
|
||||||
"style.css",
|
|
||||||
"img.png",
|
|
||||||
},
|
|
||||||
Options: &gotenberg.HTMLOptions{
|
|
||||||
HeaderFilePath: "header.html",
|
|
||||||
FooterFilePath: "footer.html",
|
|
||||||
PaperSize: gotenberg.A4,
|
|
||||||
PaperMargins: gotenberg.NormalMargins,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
dest := "foo.pdf"
|
|
||||||
c.Store(req, dest)
|
|
||||||
}
|
|
||||||
|
|
||||||
For more complete usages, head to the https://thecodingmachine.gotenberg.github.io.
|
|
||||||
*/
|
*/
|
||||||
package gotenberg
|
package gotenberg
|
||||||
|
|||||||
108
pkg/html.go
108
pkg/html.go
@@ -9,64 +9,89 @@ import (
|
|||||||
// HTMLRequest facilitates HTML conversion
|
// HTMLRequest facilitates HTML conversion
|
||||||
// with the Gotenberg API.
|
// with the Gotenberg API.
|
||||||
type HTMLRequest struct {
|
type HTMLRequest struct {
|
||||||
IndexFilePath string
|
indexFilePath string
|
||||||
AssetFilePaths []string
|
headerFilePath string
|
||||||
Options *HTMLOptions
|
footerFilePath string
|
||||||
|
assetFilePaths []string
|
||||||
|
values map[string]string
|
||||||
}
|
}
|
||||||
|
|
||||||
// HTMLOptions gathers all options
|
// NewHTMLRequest create HTMLRequest.
|
||||||
// for HTML conversion with the Gotenberg API.
|
func NewHTMLRequest(indexFilePath string) (*HTMLRequest, error) {
|
||||||
type HTMLOptions struct {
|
if !fileExists(indexFilePath) {
|
||||||
WebHookURL string
|
return nil, fmt.Errorf("%s: index file does not exist", indexFilePath)
|
||||||
HeaderFilePath string
|
}
|
||||||
FooterFilePath string
|
return &HTMLRequest{indexFilePath: indexFilePath, values: make(map[string]string)}, nil
|
||||||
PaperSize [2]float64
|
|
||||||
PaperMargins [4]float64
|
|
||||||
Landscape bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (html *HTMLRequest) validate() error {
|
// SetWebhookURL sets webhookURL form field.
|
||||||
if !fileExists(html.IndexFilePath) {
|
func (html *HTMLRequest) SetWebhookURL(webhookURL string) {
|
||||||
return fmt.Errorf("%s: index file does not exist", html.IndexFilePath)
|
html.values[webhookURL] = webhookURL
|
||||||
}
|
}
|
||||||
if html.Options.HeaderFilePath != "" && !fileExists(html.Options.HeaderFilePath) {
|
|
||||||
return fmt.Errorf("%s: header file does not exist", html.Options.HeaderFilePath)
|
// SetHeader sets header form file.
|
||||||
}
|
func (html *HTMLRequest) SetHeader(fpath string) error {
|
||||||
if html.Options.FooterFilePath != "" && !fileExists(html.Options.FooterFilePath) {
|
if !fileExists(fpath) {
|
||||||
return fmt.Errorf("%s: footer file does not exist", html.Options.FooterFilePath)
|
return fmt.Errorf("%s: header file does not exist", fpath)
|
||||||
}
|
}
|
||||||
|
html.headerFilePath = fpath
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetFooter sets footer form file.
|
||||||
|
func (html *HTMLRequest) SetFooter(fpath string) error {
|
||||||
|
if !fileExists(fpath) {
|
||||||
|
return fmt.Errorf("%s: footer file does not exist", fpath)
|
||||||
|
}
|
||||||
|
html.footerFilePath = fpath
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetAssets sets assets form files.
|
||||||
|
func (html *HTMLRequest) SetAssets(fpaths []string) error {
|
||||||
|
for _, fpath := range fpaths {
|
||||||
|
if !fileExists(fpath) {
|
||||||
|
return fmt.Errorf("%s: file does not exist", fpath)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
html.assetFilePaths = fpaths
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetPaperSize sets paperWidth and paperHeight form fields.
|
||||||
|
func (html *HTMLRequest) SetPaperSize(size [2]float64) {
|
||||||
|
html.values[paperWidth] = fmt.Sprintf("%f", size[0])
|
||||||
|
html.values[paperHeight] = fmt.Sprintf("%f", size[1])
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetMargins sets marginTop, marginBottom,
|
||||||
|
// marginLeft and marginRight form fields.
|
||||||
|
func (html *HTMLRequest) SetMargins(margins [4]float64) {
|
||||||
|
html.values[marginTop] = fmt.Sprintf("%f", margins[0])
|
||||||
|
html.values[marginBottom] = fmt.Sprintf("%f", margins[1])
|
||||||
|
html.values[marginLeft] = fmt.Sprintf("%f", margins[2])
|
||||||
|
html.values[marginRight] = fmt.Sprintf("%f", margins[3])
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetLandscape sets landscape form field.
|
||||||
|
func (html *HTMLRequest) SetLandscape(isLandscape bool) {
|
||||||
|
html.values[landscape] = strconv.FormatBool(isLandscape)
|
||||||
|
}
|
||||||
|
|
||||||
func (html *HTMLRequest) getPostURL() string {
|
func (html *HTMLRequest) getPostURL() string {
|
||||||
return "/convert/html"
|
return "/convert/html"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (html *HTMLRequest) getFormValues() map[string]string {
|
func (html *HTMLRequest) getFormValues() map[string]string {
|
||||||
if html.Options == nil {
|
return html.values
|
||||||
html.Options = &HTMLOptions{}
|
|
||||||
}
|
|
||||||
values := make(map[string]string)
|
|
||||||
values[webhookURL] = html.Options.WebHookURL
|
|
||||||
values[paperWidth] = fmt.Sprintf("%f", html.Options.PaperSize[0])
|
|
||||||
values[paperHeight] = fmt.Sprintf("%f", html.Options.PaperSize[1])
|
|
||||||
values[marginTop] = fmt.Sprintf("%f", html.Options.PaperMargins[0])
|
|
||||||
values[marginBottom] = fmt.Sprintf("%f", html.Options.PaperMargins[1])
|
|
||||||
values[marginLeft] = fmt.Sprintf("%f", html.Options.PaperMargins[2])
|
|
||||||
values[marginRight] = fmt.Sprintf("%f", html.Options.PaperMargins[3])
|
|
||||||
values[landscape] = strconv.FormatBool(html.Options.Landscape)
|
|
||||||
return values
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (html *HTMLRequest) getFormFiles() map[string]string {
|
func (html *HTMLRequest) getFormFiles() map[string]string {
|
||||||
if html.Options == nil {
|
|
||||||
html.Options = &HTMLOptions{}
|
|
||||||
}
|
|
||||||
files := make(map[string]string)
|
files := make(map[string]string)
|
||||||
files["index.html"] = html.IndexFilePath
|
files["index.html"] = html.indexFilePath
|
||||||
files["header.html"] = html.Options.HeaderFilePath
|
files["header.html"] = html.headerFilePath
|
||||||
files["footer.html"] = html.Options.FooterFilePath
|
files["footer.html"] = html.footerFilePath
|
||||||
for _, fpath := range html.AssetFilePaths {
|
for _, fpath := range html.assetFilePaths {
|
||||||
files[filepath.Base(fpath)] = fpath
|
files[filepath.Base(fpath)] = fpath
|
||||||
}
|
}
|
||||||
return files
|
return files
|
||||||
@@ -75,4 +100,5 @@ func (html *HTMLRequest) getFormFiles() map[string]string {
|
|||||||
// Compile-time checks to ensure type implements desired interfaces.
|
// Compile-time checks to ensure type implements desired interfaces.
|
||||||
var (
|
var (
|
||||||
_ = Request(new(HTMLRequest))
|
_ = Request(new(HTMLRequest))
|
||||||
|
_ = ChromeRequest(new(HTMLRequest))
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -13,20 +13,21 @@ import (
|
|||||||
|
|
||||||
func TestHTML(t *testing.T) {
|
func TestHTML(t *testing.T) {
|
||||||
c := &Client{Hostname: "http://localhost:3000"}
|
c := &Client{Hostname: "http://localhost:3000"}
|
||||||
req := &HTMLRequest{
|
req, err := NewHTMLRequest(test.HTMLTestFilePath(t, "index.html"))
|
||||||
IndexFilePath: test.HTMLTestFilePath(t, "index.html"),
|
require.Nil(t, err)
|
||||||
AssetFilePaths: []string{
|
err = req.SetHeader(test.HTMLTestFilePath(t, "header.html"))
|
||||||
test.HTMLTestFilePath(t, "font.woff"),
|
require.Nil(t, err)
|
||||||
test.HTMLTestFilePath(t, "img.gif"),
|
err = req.SetFooter(test.HTMLTestFilePath(t, "footer.html"))
|
||||||
test.HTMLTestFilePath(t, "style.css"),
|
require.Nil(t, err)
|
||||||
},
|
err = req.SetAssets([]string{
|
||||||
Options: &HTMLOptions{
|
test.HTMLTestFilePath(t, "font.woff"),
|
||||||
HeaderFilePath: test.HTMLTestFilePath(t, "header.html"),
|
test.HTMLTestFilePath(t, "img.gif"),
|
||||||
FooterFilePath: test.HTMLTestFilePath(t, "footer.html"),
|
test.HTMLTestFilePath(t, "style.css"),
|
||||||
PaperSize: A4,
|
})
|
||||||
PaperMargins: NormalMargins,
|
require.Nil(t, err)
|
||||||
},
|
req.SetPaperSize(A4)
|
||||||
}
|
req.SetMargins(NormalMargins)
|
||||||
|
req.SetLandscape(false)
|
||||||
dirPath, err := rand.Get()
|
dirPath, err := rand.Get()
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
dest := fmt.Sprintf("%s/foo.pdf", dirPath)
|
dest := fmt.Sprintf("%s/foo.pdf", dirPath)
|
||||||
|
|||||||
124
pkg/markdown.go
124
pkg/markdown.go
@@ -9,73 +9,102 @@ import (
|
|||||||
// MarkdownRequest facilitates Markdown conversion
|
// MarkdownRequest facilitates Markdown conversion
|
||||||
// with the Gotenberg API.
|
// with the Gotenberg API.
|
||||||
type MarkdownRequest struct {
|
type MarkdownRequest struct {
|
||||||
IndexFilePath string
|
indexFilePath string
|
||||||
MarkdownFilePaths []string
|
markdownFilePaths []string
|
||||||
AssetFilePaths []string
|
headerFilePath string
|
||||||
Options *MarkdownOptions
|
footerFilePath string
|
||||||
|
assetFilePaths []string
|
||||||
|
values map[string]string
|
||||||
}
|
}
|
||||||
|
|
||||||
// MarkdownOptions gathers all options
|
// NewMarkdownRequest create MarkdownRequest.
|
||||||
// for Markdown conversion with the Gotenberg API.
|
func NewMarkdownRequest(indexFilePath string, markdownFilePaths []string) (*MarkdownRequest, error) {
|
||||||
type MarkdownOptions struct {
|
if !fileExists(indexFilePath) {
|
||||||
WebHookURL string
|
return nil, fmt.Errorf("%s: index file does not exist", indexFilePath)
|
||||||
HeaderFilePath string
|
|
||||||
FooterFilePath string
|
|
||||||
PaperSize [2]float64
|
|
||||||
PaperMargins [4]float64
|
|
||||||
Landscape bool
|
|
||||||
}
|
|
||||||
|
|
||||||
func (markdown *MarkdownRequest) validate() error {
|
|
||||||
if !fileExists(markdown.IndexFilePath) {
|
|
||||||
return fmt.Errorf("%s: index file does not exist", markdown.IndexFilePath)
|
|
||||||
}
|
}
|
||||||
if markdown.Options.HeaderFilePath != "" && !fileExists(markdown.Options.HeaderFilePath) {
|
for _, fpath := range markdownFilePaths {
|
||||||
return fmt.Errorf("%s: header file does not exist", markdown.Options.HeaderFilePath)
|
|
||||||
}
|
|
||||||
if markdown.Options.FooterFilePath != "" && !fileExists(markdown.Options.FooterFilePath) {
|
|
||||||
return fmt.Errorf("%s: footer file does not exist", markdown.Options.FooterFilePath)
|
|
||||||
}
|
|
||||||
for _, fpath := range markdown.MarkdownFilePaths {
|
|
||||||
if !fileExists(fpath) {
|
if !fileExists(fpath) {
|
||||||
return fmt.Errorf("%s: markdown file does not exist", fpath)
|
return nil, fmt.Errorf("%s: markdown file does not exist", fpath)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return &MarkdownRequest{
|
||||||
|
indexFilePath: indexFilePath,
|
||||||
|
markdownFilePaths: markdownFilePaths,
|
||||||
|
values: make(map[string]string),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetWebhookURL sets webhookURL form field.
|
||||||
|
func (markdown *MarkdownRequest) SetWebhookURL(webhookURL string) {
|
||||||
|
markdown.values[webhookURL] = webhookURL
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetHeader sets header form file.
|
||||||
|
func (markdown *MarkdownRequest) SetHeader(fpath string) error {
|
||||||
|
if !fileExists(fpath) {
|
||||||
|
return fmt.Errorf("%s: header file does not exist", fpath)
|
||||||
|
}
|
||||||
|
markdown.headerFilePath = fpath
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetFooter sets footer form file.
|
||||||
|
func (markdown *MarkdownRequest) SetFooter(fpath string) error {
|
||||||
|
if !fileExists(fpath) {
|
||||||
|
return fmt.Errorf("%s: footer file does not exist", fpath)
|
||||||
|
}
|
||||||
|
markdown.footerFilePath = fpath
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetAssets sets assets form files.
|
||||||
|
func (markdown *MarkdownRequest) SetAssets(fpaths []string) error {
|
||||||
|
for _, fpath := range fpaths {
|
||||||
|
if !fileExists(fpath) {
|
||||||
|
return fmt.Errorf("%s: file does not exist", fpath)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
markdown.assetFilePaths = fpaths
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetPaperSize sets paperWidth and paperHeight form fields.
|
||||||
|
func (markdown *MarkdownRequest) SetPaperSize(size [2]float64) {
|
||||||
|
markdown.values[paperWidth] = fmt.Sprintf("%f", size[0])
|
||||||
|
markdown.values[paperHeight] = fmt.Sprintf("%f", size[1])
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetMargins sets marginTop, marginBottom,
|
||||||
|
// marginLeft and marginRight form fields.
|
||||||
|
func (markdown *MarkdownRequest) SetMargins(margins [4]float64) {
|
||||||
|
markdown.values[marginTop] = fmt.Sprintf("%f", margins[0])
|
||||||
|
markdown.values[marginBottom] = fmt.Sprintf("%f", margins[1])
|
||||||
|
markdown.values[marginLeft] = fmt.Sprintf("%f", margins[2])
|
||||||
|
markdown.values[marginRight] = fmt.Sprintf("%f", margins[3])
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetLandscape sets landscape form field.
|
||||||
|
func (markdown *MarkdownRequest) SetLandscape(isLandscape bool) {
|
||||||
|
markdown.values[landscape] = strconv.FormatBool(isLandscape)
|
||||||
|
}
|
||||||
|
|
||||||
func (markdown *MarkdownRequest) getPostURL() string {
|
func (markdown *MarkdownRequest) getPostURL() string {
|
||||||
return "/convert/markdown"
|
return "/convert/markdown"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (markdown *MarkdownRequest) getFormValues() map[string]string {
|
func (markdown *MarkdownRequest) getFormValues() map[string]string {
|
||||||
if markdown.Options == nil {
|
return markdown.values
|
||||||
markdown.Options = &MarkdownOptions{}
|
|
||||||
}
|
|
||||||
values := make(map[string]string)
|
|
||||||
values[webhookURL] = markdown.Options.WebHookURL
|
|
||||||
values[paperWidth] = fmt.Sprintf("%f", markdown.Options.PaperSize[0])
|
|
||||||
values[paperHeight] = fmt.Sprintf("%f", markdown.Options.PaperSize[1])
|
|
||||||
values[marginTop] = fmt.Sprintf("%f", markdown.Options.PaperMargins[0])
|
|
||||||
values[marginBottom] = fmt.Sprintf("%f", markdown.Options.PaperMargins[1])
|
|
||||||
values[marginLeft] = fmt.Sprintf("%f", markdown.Options.PaperMargins[2])
|
|
||||||
values[marginRight] = fmt.Sprintf("%f", markdown.Options.PaperMargins[3])
|
|
||||||
values[landscape] = strconv.FormatBool(markdown.Options.Landscape)
|
|
||||||
return values
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (markdown *MarkdownRequest) getFormFiles() map[string]string {
|
func (markdown *MarkdownRequest) getFormFiles() map[string]string {
|
||||||
if markdown.Options == nil {
|
|
||||||
markdown.Options = &MarkdownOptions{}
|
|
||||||
}
|
|
||||||
files := make(map[string]string)
|
files := make(map[string]string)
|
||||||
files["index.html"] = markdown.IndexFilePath
|
files["index.html"] = markdown.indexFilePath
|
||||||
files["header.html"] = markdown.Options.HeaderFilePath
|
files["header.html"] = markdown.headerFilePath
|
||||||
files["footer.html"] = markdown.Options.FooterFilePath
|
files["footer.html"] = markdown.footerFilePath
|
||||||
for _, fpath := range markdown.MarkdownFilePaths {
|
for _, fpath := range markdown.markdownFilePaths {
|
||||||
files[filepath.Base(fpath)] = fpath
|
files[filepath.Base(fpath)] = fpath
|
||||||
}
|
}
|
||||||
for _, fpath := range markdown.AssetFilePaths {
|
for _, fpath := range markdown.assetFilePaths {
|
||||||
files[filepath.Base(fpath)] = fpath
|
files[filepath.Base(fpath)] = fpath
|
||||||
}
|
}
|
||||||
return files
|
return files
|
||||||
@@ -84,4 +113,5 @@ func (markdown *MarkdownRequest) getFormFiles() map[string]string {
|
|||||||
// Compile-time checks to ensure type implements desired interfaces.
|
// Compile-time checks to ensure type implements desired interfaces.
|
||||||
var (
|
var (
|
||||||
_ = Request(new(MarkdownRequest))
|
_ = Request(new(MarkdownRequest))
|
||||||
|
_ = ChromeRequest(new(MarkdownRequest))
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -13,25 +13,28 @@ import (
|
|||||||
|
|
||||||
func TestMarkdown(t *testing.T) {
|
func TestMarkdown(t *testing.T) {
|
||||||
c := &Client{Hostname: "http://localhost:3000"}
|
c := &Client{Hostname: "http://localhost:3000"}
|
||||||
req := &MarkdownRequest{
|
req, err := NewMarkdownRequest(
|
||||||
IndexFilePath: test.MarkdownTestFilePath(t, "index.html"),
|
test.MarkdownTestFilePath(t, "index.html"),
|
||||||
MarkdownFilePaths: []string{
|
[]string{
|
||||||
test.MarkdownTestFilePath(t, "paragraph1.md"),
|
test.MarkdownTestFilePath(t, "paragraph1.md"),
|
||||||
test.MarkdownTestFilePath(t, "paragraph2.md"),
|
test.MarkdownTestFilePath(t, "paragraph2.md"),
|
||||||
test.MarkdownTestFilePath(t, "paragraph3.md"),
|
test.MarkdownTestFilePath(t, "paragraph3.md"),
|
||||||
},
|
},
|
||||||
AssetFilePaths: []string{
|
)
|
||||||
test.HTMLTestFilePath(t, "font.woff"),
|
require.Nil(t, err)
|
||||||
test.HTMLTestFilePath(t, "img.gif"),
|
err = req.SetHeader(test.MarkdownTestFilePath(t, "header.html"))
|
||||||
test.HTMLTestFilePath(t, "style.css"),
|
require.Nil(t, err)
|
||||||
},
|
err = req.SetFooter(test.MarkdownTestFilePath(t, "footer.html"))
|
||||||
Options: &MarkdownOptions{
|
require.Nil(t, err)
|
||||||
HeaderFilePath: test.MarkdownTestFilePath(t, "header.html"),
|
err = req.SetAssets([]string{
|
||||||
FooterFilePath: test.MarkdownTestFilePath(t, "footer.html"),
|
test.MarkdownTestFilePath(t, "font.woff"),
|
||||||
PaperSize: A4,
|
test.MarkdownTestFilePath(t, "img.gif"),
|
||||||
PaperMargins: NormalMargins,
|
test.MarkdownTestFilePath(t, "style.css"),
|
||||||
},
|
})
|
||||||
}
|
require.Nil(t, err)
|
||||||
|
req.SetPaperSize(A4)
|
||||||
|
req.SetMargins(NormalMargins)
|
||||||
|
req.SetLandscape(false)
|
||||||
dirPath, err := rand.Get()
|
dirPath, err := rand.Get()
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
dest := fmt.Sprintf("%s/foo.pdf", dirPath)
|
dest := fmt.Sprintf("%s/foo.pdf", dirPath)
|
||||||
|
|||||||
34
pkg/merge.go
34
pkg/merge.go
@@ -8,24 +8,23 @@ import (
|
|||||||
// MergeRequest facilitates merging PDF
|
// MergeRequest facilitates merging PDF
|
||||||
// with the Gotenberg API.
|
// with the Gotenberg API.
|
||||||
type MergeRequest struct {
|
type MergeRequest struct {
|
||||||
FilePaths []string
|
filePaths []string
|
||||||
Options *MergeOptions
|
values map[string]string
|
||||||
}
|
}
|
||||||
|
|
||||||
// MergeOptions gathers all options
|
// NewMergeRequest create MergeRequest.
|
||||||
// for merging PDF
|
func NewMergeRequest(fpaths []string) (*MergeRequest, error) {
|
||||||
// with the Gotenberg API.
|
for _, fpath := range fpaths {
|
||||||
type MergeOptions struct {
|
|
||||||
WebHookURL string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (merge *MergeRequest) validate() error {
|
|
||||||
for _, fpath := range merge.FilePaths {
|
|
||||||
if !fileExists(fpath) {
|
if !fileExists(fpath) {
|
||||||
return fmt.Errorf("%s: PDF file does not exist", fpath)
|
return nil, fmt.Errorf("%s: file does not exist", fpath)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return &MergeRequest{filePaths: fpaths, values: make(map[string]string)}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetWebhookURL sets webhookURL form field.
|
||||||
|
func (merge *MergeRequest) SetWebhookURL(webhookURL string) {
|
||||||
|
merge.values[webhookURL] = webhookURL
|
||||||
}
|
}
|
||||||
|
|
||||||
func (merge *MergeRequest) getPostURL() string {
|
func (merge *MergeRequest) getPostURL() string {
|
||||||
@@ -33,17 +32,12 @@ func (merge *MergeRequest) getPostURL() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (merge *MergeRequest) getFormValues() map[string]string {
|
func (merge *MergeRequest) getFormValues() map[string]string {
|
||||||
if merge.Options == nil {
|
return merge.values
|
||||||
merge.Options = &MergeOptions{}
|
|
||||||
}
|
|
||||||
values := make(map[string]string)
|
|
||||||
values[webhookURL] = merge.Options.WebHookURL
|
|
||||||
return values
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (merge *MergeRequest) getFormFiles() map[string]string {
|
func (merge *MergeRequest) getFormFiles() map[string]string {
|
||||||
files := make(map[string]string)
|
files := make(map[string]string)
|
||||||
for _, fpath := range merge.FilePaths {
|
for _, fpath := range merge.filePaths {
|
||||||
files[filepath.Base(fpath)] = fpath
|
files[filepath.Base(fpath)] = fpath
|
||||||
}
|
}
|
||||||
return files
|
return files
|
||||||
|
|||||||
@@ -13,12 +13,11 @@ import (
|
|||||||
|
|
||||||
func TestMerge(t *testing.T) {
|
func TestMerge(t *testing.T) {
|
||||||
c := &Client{Hostname: "http://localhost:3000"}
|
c := &Client{Hostname: "http://localhost:3000"}
|
||||||
req := &MergeRequest{
|
req, err := NewMergeRequest([]string{
|
||||||
FilePaths: []string{
|
test.PDFTestFilePath(t, "gotenberg.pdf"),
|
||||||
test.PDFTestFilePath(t, "gotenberg.pdf"),
|
test.PDFTestFilePath(t, "gotenberg.pdf"),
|
||||||
test.PDFTestFilePath(t, "gotenberg.pdf"),
|
})
|
||||||
},
|
require.Nil(t, err)
|
||||||
}
|
|
||||||
dirPath, err := rand.Get()
|
dirPath, err := rand.Get()
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
dest := fmt.Sprintf("%s/foo.pdf", dirPath)
|
dest := fmt.Sprintf("%s/foo.pdf", dirPath)
|
||||||
|
|||||||
@@ -3,29 +3,40 @@ package gotenberg
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"strconv"
|
||||||
)
|
)
|
||||||
|
|
||||||
// OfficeRequest facilitates Office documents
|
// OfficeRequest facilitates Office documents
|
||||||
// conversion with the Gotenberg API.
|
// conversion with the Gotenberg API.
|
||||||
type OfficeRequest struct {
|
type OfficeRequest struct {
|
||||||
FilePaths []string
|
filePaths []string
|
||||||
Options *OfficeOptions
|
values map[string]string
|
||||||
}
|
}
|
||||||
|
|
||||||
// OfficeOptions gathers all options
|
// NewOfficeRequest create OfficeRequest.
|
||||||
// for Office documents conversion
|
func NewOfficeRequest(fpaths []string) (*OfficeRequest, error) {
|
||||||
// with the Gotenberg API.
|
for _, fpath := range fpaths {
|
||||||
type OfficeOptions struct {
|
|
||||||
WebHookURL string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (office *OfficeRequest) validate() error {
|
|
||||||
for _, fpath := range office.FilePaths {
|
|
||||||
if !fileExists(fpath) {
|
if !fileExists(fpath) {
|
||||||
return fmt.Errorf("%s: office file does not exist", fpath)
|
return nil, fmt.Errorf("%s: file does not exist", fpath)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return &OfficeRequest{filePaths: fpaths, values: make(map[string]string)}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetWebhookURL sets webhookURL form field.
|
||||||
|
func (office *OfficeRequest) SetWebhookURL(webhookURL string) {
|
||||||
|
office.values[webhookURL] = webhookURL
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetPaperSize sets paperWidth and paperHeight form fields.
|
||||||
|
func (office *OfficeRequest) SetPaperSize(size [2]float64) {
|
||||||
|
office.values[paperWidth] = fmt.Sprintf("%f", size[0])
|
||||||
|
office.values[paperHeight] = fmt.Sprintf("%f", size[1])
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetLandscape sets landscape form field.
|
||||||
|
func (office *OfficeRequest) SetLandscape(isLandscape bool) {
|
||||||
|
office.values[landscape] = strconv.FormatBool(isLandscape)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (office *OfficeRequest) getPostURL() string {
|
func (office *OfficeRequest) getPostURL() string {
|
||||||
@@ -33,17 +44,12 @@ func (office *OfficeRequest) getPostURL() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (office *OfficeRequest) getFormValues() map[string]string {
|
func (office *OfficeRequest) getFormValues() map[string]string {
|
||||||
if office.Options == nil {
|
return office.values
|
||||||
office.Options = &OfficeOptions{}
|
|
||||||
}
|
|
||||||
values := make(map[string]string)
|
|
||||||
values[webhookURL] = office.Options.WebHookURL
|
|
||||||
return values
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (office *OfficeRequest) getFormFiles() map[string]string {
|
func (office *OfficeRequest) getFormFiles() map[string]string {
|
||||||
files := make(map[string]string)
|
files := make(map[string]string)
|
||||||
for _, fpath := range office.FilePaths {
|
for _, fpath := range office.filePaths {
|
||||||
files[filepath.Base(fpath)] = fpath
|
files[filepath.Base(fpath)] = fpath
|
||||||
}
|
}
|
||||||
return files
|
return files
|
||||||
@@ -52,4 +58,5 @@ func (office *OfficeRequest) getFormFiles() map[string]string {
|
|||||||
// Compile-time checks to ensure type implements desired interfaces.
|
// Compile-time checks to ensure type implements desired interfaces.
|
||||||
var (
|
var (
|
||||||
_ = Request(new(OfficeRequest))
|
_ = Request(new(OfficeRequest))
|
||||||
|
_ = UnoconvRequest(new(OfficeRequest))
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -13,11 +13,12 @@ import (
|
|||||||
|
|
||||||
func TestOffice(t *testing.T) {
|
func TestOffice(t *testing.T) {
|
||||||
c := &Client{Hostname: "http://localhost:3000"}
|
c := &Client{Hostname: "http://localhost:3000"}
|
||||||
req := &OfficeRequest{
|
req, err := NewOfficeRequest([]string{
|
||||||
FilePaths: []string{
|
test.OfficeTestFilePath(t, "document.docx"),
|
||||||
test.OfficeTestFilePath(t, "document.docx"),
|
})
|
||||||
},
|
require.Nil(t, err)
|
||||||
}
|
req.SetPaperSize(A4)
|
||||||
|
req.SetLandscape(false)
|
||||||
dirPath, err := rand.Get()
|
dirPath, err := rand.Get()
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
dest := fmt.Sprintf("%s/foo.pdf", dirPath)
|
dest := fmt.Sprintf("%s/foo.pdf", dirPath)
|
||||||
|
|||||||
2196
test/testdata/office/document.rtf
vendored
Normal file
2196
test/testdata/office/document.rtf
vendored
Normal file
File diff suppressed because it is too large
Load Diff
3
test/testdata/office/document.txt
vendored
Normal file
3
test/testdata/office/document.txt
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
Gutenberg
|
||||||
|
|
||||||
|
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
|
||||||
BIN
test/testdata/pdf/gotenberg_bis.pdf
vendored
Normal file
BIN
test/testdata/pdf/gotenberg_bis.pdf
vendored
Normal file
Binary file not shown.
Reference in New Issue
Block a user