Compare commits
8 Commits
28aa7507a6
...
report
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f03abc8ac8 | ||
|
|
d89900ba25 | ||
|
|
4a3c33690c | ||
|
|
d77e676692 | ||
|
|
395b328c58 | ||
|
|
bf97b6c542 | ||
|
|
b6399b405e | ||
|
|
58a610f541 |
28
.gitea/workflows/build.yaml
Normal file
28
.gitea/workflows/build.yaml
Normal file
@@ -0,0 +1,28 @@
|
||||
name: Main CI/CD
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
|
||||
jobs:
|
||||
build-and-push:
|
||||
name: Build and push
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
- uses: docker/login-action@v1
|
||||
with:
|
||||
registry: registry.btwazure.com
|
||||
username: ${{ secrets.HARBOR_USERNAME }}
|
||||
password: ${{ secrets.HARBOR_PASSWORD }}
|
||||
- name: Build & Push
|
||||
env:
|
||||
REGISTRY: ${{ secrets.REGISTRY }}
|
||||
IMAGE_TAG: ${{gitea.sha}}
|
||||
run: |
|
||||
docker build --pull --no-cache=true --tag $REGISTRY --tag $REGISTRY:$IMAGE_TAG .
|
||||
docker push $REGISTRY
|
||||
docker push $REGISTRY:$IMAGE_TAG
|
||||
docker rmi $(docker images -q $REGISTRY:$IMAGE_TAG) -f
|
||||
6
.gitignore
vendored
6
.gitignore
vendored
@@ -1 +1,5 @@
|
||||
/vendor
|
||||
/vendor
|
||||
**/.DS_Store
|
||||
**/.~lock*
|
||||
app
|
||||
build
|
||||
50
Dockerfile
Normal file
50
Dockerfile
Normal file
@@ -0,0 +1,50 @@
|
||||
FROM golang:1.23-alpine AS build
|
||||
|
||||
COPY ./gosrc/ /build
|
||||
|
||||
WORKDIR /build
|
||||
|
||||
RUN go mod download
|
||||
|
||||
RUN go build -ldflags="-s -w" -o ./dist/app
|
||||
|
||||
|
||||
FROM php:8.2-cli
|
||||
|
||||
# Install dependencies needed for Composer and PHP zip extension
|
||||
RUN echo "deb http://deb.debian.org/debian bookworm contrib non-free" > /etc/apt/sources.list.d/contrib.list
|
||||
RUN apt-get update && apt-get install -y \
|
||||
curl \
|
||||
unzip \
|
||||
libzip-dev \
|
||||
libreoffice \
|
||||
fontconfig \
|
||||
gcc \
|
||||
g++ \
|
||||
build-essential \
|
||||
ttf-mscorefonts-installer \
|
||||
&& docker-php-ext-install zip \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Install fonts
|
||||
RUN mkdir -p /usr/share/fonts/truetype/custom
|
||||
COPY ./fonts/gilroy/* /usr/share/fonts/truetype/custom
|
||||
COPY ./fonts/lexend/* /usr/share/fonts/truetype/custom
|
||||
COPY ./fonts/visby/* /usr/share/fonts/truetype/custom
|
||||
RUN fc-cache -f -v
|
||||
|
||||
# Download and install Composer
|
||||
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
|
||||
|
||||
# Verify Composer installation
|
||||
RUN composer --version
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY . .
|
||||
|
||||
COPY --from=build /build/dist/app .
|
||||
|
||||
RUN rm -rf gosrc && composer install
|
||||
|
||||
CMD [ "/app/app" ]
|
||||
25
base.Dockerfile
Normal file
25
base.Dockerfile
Normal file
@@ -0,0 +1,25 @@
|
||||
FROM php:8.2-cli
|
||||
|
||||
# Install dependencies needed for Composer and PHP zip extension
|
||||
RUN echo "deb http://deb.debian.org/debian bookworm contrib non-free" > /etc/apt/sources.list.d/contrib.list
|
||||
RUN apt-get update && apt-get install -y \
|
||||
curl \
|
||||
unzip \
|
||||
libzip-dev \
|
||||
libreoffice \
|
||||
fontconfig \
|
||||
gcc \
|
||||
g++ \
|
||||
build-essential \
|
||||
ttf-mscorefonts-installer \
|
||||
&& docker-php-ext-install zip \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Install fonts
|
||||
RUN mkdir -p /usr/share/fonts/truetype/custom
|
||||
COPY ./fonts/gilroy/* /usr/share/fonts/truetype/custom
|
||||
COPY ./fonts/lexend/* /usr/share/fonts/truetype/custom
|
||||
RUN fc-cache -f -v
|
||||
|
||||
# Download and install Composer
|
||||
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
|
||||
@@ -8,6 +8,9 @@ RUN apt-get update && apt-get install -y \
|
||||
libzip-dev \
|
||||
libreoffice \
|
||||
fontconfig \
|
||||
gcc \
|
||||
g++ \
|
||||
build-essential \
|
||||
ttf-mscorefonts-installer \
|
||||
&& docker-php-ext-install zip \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
@@ -16,6 +19,7 @@ RUN apt-get update && apt-get install -y \
|
||||
RUN mkdir -p /usr/share/fonts/truetype/custom
|
||||
COPY ./fonts/gilroy/* /usr/share/fonts/truetype/custom
|
||||
COPY ./fonts/lexend/* /usr/share/fonts/truetype/custom
|
||||
COPY ./fonts/visby/* /usr/share/fonts/truetype/custom
|
||||
RUN fc-cache -f -v
|
||||
|
||||
# Download and install Composer
|
||||
@@ -24,6 +28,21 @@ RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local
|
||||
# Verify Composer installation
|
||||
RUN composer --version
|
||||
|
||||
WORKDIR /app
|
||||
# Install Golang
|
||||
RUN curl -OL https://go.dev/dl/go1.23.0.linux-arm64.tar.gz \
|
||||
&& tar -C /usr/local -xzf go1.23.0.linux-arm64.tar.gz \
|
||||
&& rm go1.23.0.linux-arm64.tar.gz
|
||||
|
||||
CMD ["tail","-f", "/dev/null"]
|
||||
# Set Go environment variables
|
||||
ENV PATH="/usr/local/go/bin:${PATH}"
|
||||
|
||||
# Verify Go installation
|
||||
RUN go version
|
||||
|
||||
RUN curl -sSfL https://raw.githubusercontent.com/cosmtrek/air/master/install.sh | sh -s -- -b /usr/local/bin
|
||||
|
||||
WORKDIR /app/gosrc
|
||||
|
||||
CMD ["air", "-c", ".air.toml", "--", "run"]
|
||||
|
||||
EXPOSE 80
|
||||
|
||||
@@ -5,3 +5,5 @@ services:
|
||||
dockerfile: dev.Dockerfile
|
||||
volumes:
|
||||
- ./:/app
|
||||
ports:
|
||||
- 8080:80
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
,pande,pandewidya.local,15.08.2024 07:34,file:///Users/pande/Library/Application%20Support/LibreOffice/4;
|
||||
BIN
examples/Cover.png
Normal file
BIN
examples/Cover.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.8 MiB |
BIN
examples/Raport.docx
Normal file
BIN
examples/Raport.docx
Normal file
Binary file not shown.
5058
examples/pembahasan.json
Normal file
5058
examples/pembahasan.json
Normal file
File diff suppressed because it is too large
Load Diff
BIN
fonts/visby/Visby Round CF Bold Oblique.otf
Normal file
BIN
fonts/visby/Visby Round CF Bold Oblique.otf
Normal file
Binary file not shown.
BIN
fonts/visby/Visby Round CF Bold.otf
Normal file
BIN
fonts/visby/Visby Round CF Bold.otf
Normal file
Binary file not shown.
BIN
fonts/visby/Visby Round CF Demibold Oblique.otf
Normal file
BIN
fonts/visby/Visby Round CF Demibold Oblique.otf
Normal file
Binary file not shown.
BIN
fonts/visby/Visby Round CF Demibold.otf
Normal file
BIN
fonts/visby/Visby Round CF Demibold.otf
Normal file
Binary file not shown.
BIN
fonts/visby/Visby Round CF Extrabold Oblique.otf
Normal file
BIN
fonts/visby/Visby Round CF Extrabold Oblique.otf
Normal file
Binary file not shown.
BIN
fonts/visby/Visby Round CF Extrabold.otf
Normal file
BIN
fonts/visby/Visby Round CF Extrabold.otf
Normal file
Binary file not shown.
BIN
fonts/visby/Visby Round CF Extralight Oblique.otf
Normal file
BIN
fonts/visby/Visby Round CF Extralight Oblique.otf
Normal file
Binary file not shown.
BIN
fonts/visby/Visby Round CF Extralight.otf
Normal file
BIN
fonts/visby/Visby Round CF Extralight.otf
Normal file
Binary file not shown.
BIN
fonts/visby/Visby Round CF Heavy Oblique.otf
Normal file
BIN
fonts/visby/Visby Round CF Heavy Oblique.otf
Normal file
Binary file not shown.
BIN
fonts/visby/Visby Round CF Heavy.otf
Normal file
BIN
fonts/visby/Visby Round CF Heavy.otf
Normal file
Binary file not shown.
BIN
fonts/visby/Visby Round CF Light Oblique.otf
Normal file
BIN
fonts/visby/Visby Round CF Light Oblique.otf
Normal file
Binary file not shown.
BIN
fonts/visby/Visby Round CF Light.otf
Normal file
BIN
fonts/visby/Visby Round CF Light.otf
Normal file
Binary file not shown.
BIN
fonts/visby/Visby Round CF Medium Oblique.otf
Normal file
BIN
fonts/visby/Visby Round CF Medium Oblique.otf
Normal file
Binary file not shown.
BIN
fonts/visby/Visby Round CF Medium.otf
Normal file
BIN
fonts/visby/Visby Round CF Medium.otf
Normal file
Binary file not shown.
BIN
fonts/visby/Visby Round CF Oblique.otf
Normal file
BIN
fonts/visby/Visby Round CF Oblique.otf
Normal file
Binary file not shown.
BIN
fonts/visby/Visby Round CF.otf
Normal file
BIN
fonts/visby/Visby Round CF.otf
Normal file
Binary file not shown.
41
gosrc/.air.toml
Normal file
41
gosrc/.air.toml
Normal file
@@ -0,0 +1,41 @@
|
||||
root = "."
|
||||
testdata_dir = "testdata"
|
||||
tmp_dir = "build"
|
||||
|
||||
[build]
|
||||
args_bin = []
|
||||
bin = "./../app"
|
||||
cmd = "go build -gcflags='all=-N -l' -o ./../app ./main.go"
|
||||
delay = 0
|
||||
exclude_dir = ["assets", "build", "vendor", "testdata", "storage"]
|
||||
exclude_file = []
|
||||
exclude_regex = ["_test.go"]
|
||||
exclude_unchanged = false
|
||||
follow_symlink = false
|
||||
include_dir = []
|
||||
include_ext = ["go", "tpl", "tmpl", "html", "yaml"]
|
||||
include_file = []
|
||||
kill_delay = "0s"
|
||||
log = "build-errors.log"
|
||||
rerun = false
|
||||
rerun_delay = 500
|
||||
send_interrupt = false
|
||||
stop_on_error = true
|
||||
|
||||
[color]
|
||||
app = ""
|
||||
build = "yellow"
|
||||
main = "magenta"
|
||||
runner = "green"
|
||||
watcher = "cyan"
|
||||
|
||||
[log]
|
||||
main_only = true
|
||||
time = true
|
||||
|
||||
[misc]
|
||||
clean_on_exit = false
|
||||
|
||||
[screen]
|
||||
clear_on_rebuild = false
|
||||
keep_scroll = true
|
||||
1
gosrc/.gitignore
vendored
Normal file
1
gosrc/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
build
|
||||
21
gosrc/go.mod
Normal file
21
gosrc/go.mod
Normal file
@@ -0,0 +1,21 @@
|
||||
module menulis.ai/genpdf
|
||||
|
||||
go 1.22.0
|
||||
|
||||
require (
|
||||
github.com/gofiber/fiber/v2 v2.52.5
|
||||
github.com/google/uuid v1.5.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/andybalholm/brotli v1.0.5 // indirect
|
||||
github.com/klauspost/compress v1.17.0 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.15 // indirect
|
||||
github.com/rivo/uniseg v0.2.0 // indirect
|
||||
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||
github.com/valyala/fasthttp v1.51.0 // indirect
|
||||
github.com/valyala/tcplisten v1.0.0 // indirect
|
||||
golang.org/x/sys v0.15.0 // indirect
|
||||
)
|
||||
27
gosrc/go.sum
Normal file
27
gosrc/go.sum
Normal file
@@ -0,0 +1,27 @@
|
||||
github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs=
|
||||
github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
|
||||
github.com/gofiber/fiber/v2 v2.52.5 h1:tWoP1MJQjGEe4GB5TUGOi7P2E0ZMMRx5ZTG4rT+yGMo=
|
||||
github.com/gofiber/fiber/v2 v2.52.5/go.mod h1:KEOE+cXMhXG0zHc9d8+E38hoX+ZN7bhOtgeF2oT6jrQ=
|
||||
github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU=
|
||||
github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/klauspost/compress v1.17.0 h1:Rnbp4K9EjcDuVuHtd0dgA4qNuv9yKDYKK1ulpJwgrqM=
|
||||
github.com/klauspost/compress v1.17.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
|
||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
|
||||
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
|
||||
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
|
||||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||
github.com/valyala/fasthttp v1.51.0 h1:8b30A5JlZ6C7AS81RsWjYMQmrZG6feChmgAolCl1SqA=
|
||||
github.com/valyala/fasthttp v1.51.0/go.mod h1:oI2XroL+lI7vdXyYoQk03bXBThfFl2cVdIA3Xl7cH8g=
|
||||
github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8=
|
||||
github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
|
||||
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
56
gosrc/main.go
Normal file
56
gosrc/main.go
Normal file
@@ -0,0 +1,56 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
var rootPath string
|
||||
|
||||
func main() {
|
||||
rootPath = os.Getenv("APP_ROOT_PATH")
|
||||
if rootPath == "" {
|
||||
rootPath = "/app"
|
||||
}
|
||||
|
||||
app := fiber.New()
|
||||
|
||||
app.Post("ebook", handleEbook)
|
||||
|
||||
log.Fatal(app.Listen(":80"))
|
||||
}
|
||||
|
||||
func handleEbook(c *fiber.Ctx) error {
|
||||
|
||||
f, err := c.FormFile("file")
|
||||
if err != nil {
|
||||
return c.Status(fiber.StatusBadRequest).SendString(fmt.Sprintf("error receiving file: %s", err))
|
||||
}
|
||||
|
||||
sp := path.Join(rootPath, fmt.Sprintf("storage/%s.json", uuid.NewString()))
|
||||
|
||||
err = c.SaveFile(f, sp)
|
||||
if err != nil {
|
||||
return c.Status(fiber.StatusInternalServerError).SendString(fmt.Sprintf("failed to save file: %s", err))
|
||||
}
|
||||
|
||||
cmd := exec.Command(path.Join(rootPath, "genpdf"), "generate:ebook", sp)
|
||||
|
||||
o, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
return c.Status(fiber.StatusInternalServerError).SendString(fmt.Sprintf("failed to convert ebook: %s", string(o)))
|
||||
}
|
||||
err = c.Download(strings.TrimSpace(string(o)))
|
||||
if err != nil {
|
||||
return c.Status(fiber.StatusInternalServerError).SendString(fmt.Sprintf("failed to sending ebook: %s", err))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
BIN
src/.DS_Store
vendored
BIN
src/.DS_Store
vendored
Binary file not shown.
@@ -10,9 +10,9 @@ use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Process\Process;
|
||||
use Symfony\Component\Process\Exception\ProcessFailedException;
|
||||
|
||||
class Generate extends Command
|
||||
class GenerateEbook extends Command
|
||||
{
|
||||
protected static $defaultName = "generate";
|
||||
protected static $defaultName = "generate:ebook";
|
||||
|
||||
protected function configure()
|
||||
{
|
||||
@@ -35,7 +35,7 @@ class Generate extends Command
|
||||
"--convert-to",
|
||||
"pdf",
|
||||
"--outdir",
|
||||
"storage/",
|
||||
"/app/storage/",
|
||||
$path
|
||||
]);
|
||||
|
||||
@@ -45,7 +45,7 @@ class Generate extends Command
|
||||
throw new ProcessFailedException($cmd);
|
||||
}
|
||||
|
||||
$output->writeln($cmd->getOutput());
|
||||
$output->writeln(rootPath("storage/" . pathinfo($path, PATHINFO_FILENAME) . ".pdf"));
|
||||
|
||||
return Command::SUCCESS;
|
||||
}
|
||||
55
src/Command/GenerateTest.php
Normal file
55
src/Command/GenerateTest.php
Normal file
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
namespace MenulisAi\Pdfgen\Command;
|
||||
|
||||
use MenulisAi\Pdfgen\Document\Ebook;
|
||||
use MenulisAi\Pdfgen\Document\Table;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Process\Process;
|
||||
use Symfony\Component\Process\Exception\ProcessFailedException;
|
||||
|
||||
class GenerateTest extends Command
|
||||
{
|
||||
protected static $defaultName = "generate:test";
|
||||
|
||||
protected function configure()
|
||||
{
|
||||
$this->setDescription('Generate a PDF document file from JSON data')
|
||||
->addArgument("input", InputArgument::REQUIRED, "Input path file JSON")
|
||||
->addArgument("output", InputArgument::OPTIONAL, "Set the output path");
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output): int
|
||||
{
|
||||
$inPath = $input->getArgument("input");
|
||||
|
||||
$doc = new Table($inPath);
|
||||
|
||||
$path = $doc->compile();
|
||||
|
||||
$output->writeln($path);
|
||||
|
||||
$cmd = new Process([
|
||||
"soffice",
|
||||
"--headless",
|
||||
"--convert-to",
|
||||
"pdf",
|
||||
"--outdir",
|
||||
"/app/storage/",
|
||||
$path
|
||||
]);
|
||||
|
||||
$cmd->run();
|
||||
|
||||
if (!$cmd->isSuccessful()) {
|
||||
throw new ProcessFailedException($cmd);
|
||||
}
|
||||
|
||||
$output->writeln(rootPath("storage/" . pathinfo($path, PATHINFO_FILENAME) . ".pdf"));
|
||||
|
||||
return Command::SUCCESS;
|
||||
}
|
||||
}
|
||||
@@ -2,4 +2,25 @@
|
||||
|
||||
namespace MenulisAi\Pdfgen\Document;
|
||||
|
||||
interface Document {}
|
||||
use Exception;
|
||||
|
||||
class Document
|
||||
{
|
||||
protected $object;
|
||||
|
||||
protected function openFile(string $path)
|
||||
{
|
||||
$file = file_get_contents($path);
|
||||
if ($file === false) {
|
||||
throw new Exception("Unable to read or open the file", 1);
|
||||
}
|
||||
|
||||
$data = json_decode($file);
|
||||
if (json_last_error() !== JSON_ERROR_NONE) {
|
||||
// Handle error if the JSON could not be parsed
|
||||
throw new Exception("Error read the json file: " . json_last_error_msg(), 1);
|
||||
}
|
||||
|
||||
$this->object = $data;
|
||||
}
|
||||
}
|
||||
|
||||
9
src/Document/Documentable.php
Normal file
9
src/Document/Documentable.php
Normal file
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace MenulisAi\Pdfgen\Document;
|
||||
|
||||
interface Documentable
|
||||
{
|
||||
public function templateSource(): string;
|
||||
public function compile(): string;
|
||||
}
|
||||
@@ -5,10 +5,8 @@ namespace MenulisAi\Pdfgen\Document;
|
||||
use PhpOffice\PhpWord\TemplateProcessor;
|
||||
use Exception;
|
||||
|
||||
class Ebook implements Document
|
||||
class Ebook extends Document implements Documentable
|
||||
{
|
||||
protected $object;
|
||||
|
||||
public function __construct(string $jsonPath)
|
||||
{
|
||||
$this->openFile($jsonPath);
|
||||
@@ -114,21 +112,7 @@ class Ebook implements Document
|
||||
return $proc->save();
|
||||
}
|
||||
|
||||
protected function openFile(string $path)
|
||||
{
|
||||
$file = file_get_contents($path);
|
||||
if ($file === false) {
|
||||
throw new Exception("Unable to read or open the file", 1);
|
||||
}
|
||||
|
||||
$data = json_decode($file);
|
||||
if (json_last_error() !== JSON_ERROR_NONE) {
|
||||
// Handle error if the JSON could not be parsed
|
||||
throw new Exception("Error read the json file: " . json_last_error_msg(), 1);
|
||||
}
|
||||
|
||||
$this->object = $data;
|
||||
}
|
||||
|
||||
protected function intToAlphabet(int $number): string
|
||||
{
|
||||
|
||||
103
src/Document/Table.php
Normal file
103
src/Document/Table.php
Normal file
@@ -0,0 +1,103 @@
|
||||
<?php
|
||||
|
||||
namespace MenulisAi\Pdfgen\Document;
|
||||
|
||||
use PhpOffice\PhpWord\Element\Table as ElementTable;
|
||||
use PhpOffice\PhpWord\IOFactory;
|
||||
use PhpOffice\PhpWord\SimpleType\Border;
|
||||
use PhpOffice\PhpWord\SimpleType\Jc;
|
||||
use PhpOffice\PhpWord\SimpleType\JcTable;
|
||||
use PhpOffice\PhpWord\TemplateProcessor;
|
||||
use PhpOffice\PhpWord\SimpleType\TblWidth;
|
||||
use PhpOffice\PhpWord\SimpleType\TextAlignment;
|
||||
use PhpOffice\PhpWord\Style\Table as StyleTable;
|
||||
|
||||
const PER_INCH = 1440;
|
||||
|
||||
class Table extends Document implements Documentable
|
||||
{
|
||||
public function __construct(string $jsonPath)
|
||||
{
|
||||
// $this->openFile($jsonPath);
|
||||
}
|
||||
|
||||
public function templateSource(): string
|
||||
{
|
||||
return appPath("Template/Doc1.docx");
|
||||
}
|
||||
|
||||
public function compile(): string
|
||||
{
|
||||
/**
|
||||
* 1 Inch = 1440 point for TWIP / dxa
|
||||
* A4 Paper (W x H) = 8.27 x 11.69 = 11908.9 x 16833.6
|
||||
* Margin Left = 0.44" = 633.6
|
||||
* Margin Right = 0.44" = 633.6
|
||||
* Margin Top = 0.79" = 1137.6
|
||||
* Margin Bottom = 0.79" = 1137.6
|
||||
*/
|
||||
|
||||
$proc = new TemplateProcessor($this->templateSource());
|
||||
|
||||
$proc->setValue("name", "Pande Ganteng");
|
||||
$proc->setValue("full_name", "Pande Ganteng");
|
||||
$proc->setValue("email", "Pande@gmail.com");
|
||||
|
||||
$tableWidth = (8.27 * PER_INCH) - ((0.44 * 2) * PER_INCH);
|
||||
$col1Width = $tableWidth * 0.4;
|
||||
$col2Width = $tableWidth * 0.15;
|
||||
$col3Width = $tableWidth * 0.15;
|
||||
$col4Width = $tableWidth * 0.15;
|
||||
$col5Width = $tableWidth * 0.15;
|
||||
|
||||
$table = new ElementTable([
|
||||
'alignment' => JcTable::CENTER,
|
||||
'borderColor' => '#072442',
|
||||
'borderSize' => 10,
|
||||
'width' => $tableWidth,
|
||||
'unit' => TblWidth::TWIP,
|
||||
'layout' => StyleTable::LAYOUT_AUTO,
|
||||
'cellMarginTop' => 100,
|
||||
'cellMarginLeft' => 100,
|
||||
'cellMarginBottom' => 0,
|
||||
'cellMarginRight' => 100,
|
||||
]);
|
||||
$table->addRow(800);
|
||||
$table->addCell($col1Width, ['valign' => 'center', 'bgColor' => '#4169E1'])->addText('Kategori', ['bold' => true, 'name' => 'Visby Round CF', 'size' => 10, 'color' => '#ffffff'], ['alignment' => Jc::CENTER]);
|
||||
$table->addCell($col2Width, ['valign' => 'center', 'bgColor' => '#4169E1'])->addText('Jawaban Benar', ['bold' => true, 'name' => 'Visby Round CF', 'size' => 10, 'color' => '#ffffff'], ['alignment' => Jc::CENTER]);
|
||||
$table->addCell($col3Width, ['valign' => 'center', 'bgColor' => '#4169E1'])->addText('Jawaban Salah', ['bold' => true, 'name' => 'Visby Round CF', 'size' => 10, 'color' => '#ffffff'], ['alignment' => Jc::CENTER]);
|
||||
$table->addCell($col4Width, ['valign' => 'center', 'bgColor' => '#4169E1'])->addText('Tidak Menjawab', ['bold' => true, 'name' => 'Visby Round CF', 'size' => 10, 'color' => '#ffffff'], ['alignment' => Jc::CENTER]);
|
||||
$table->addCell($col5Width, ['valign' => 'center', 'bgColor' => '#4169E1'])->addText('% Jawaban Benar', ['bold' => true, 'name' => 'Visby Round CF', 'size' => 10, 'color' => '#ffffff'], ['alignment' => Jc::CENTER]);
|
||||
|
||||
// TWK
|
||||
$table->addRow();
|
||||
$table->addCell($col1Width, ['valign' => 'center', 'bgColor' => '#f0f3fd', 'borderBottomSize' => 0, 'borderBottomStyle' => Border::NONE])->addText("Tes Wawasan Kebangsaan", ['bold' => true, 'name' => 'Visby Round CF', 'size' => 9, 'color' => '#072442']);
|
||||
$table->addCell($col2Width, ['valign' => 'center', 'bgColor' => '#f0f3fd', 'borderBottomSize' => 0, 'borderBottomStyle' => Border::NONE])->addText("17", ['bold' => true, 'name' => 'Visby Round CF', 'size' => 9, 'color' => '#072442'], ['alignment' => Jc::CENTER]);
|
||||
$table->addCell($col3Width, ['valign' => 'center', 'bgColor' => '#f0f3fd', 'borderBottomSize' => 0, 'borderBottomStyle' => Border::NONE])->addText("13", ['bold' => true, 'name' => 'Visby Round CF', 'size' => 9, 'color' => '#072442'], ['alignment' => Jc::CENTER]);
|
||||
$table->addCell($col4Width, ['valign' => 'center', 'bgColor' => '#f0f3fd', 'borderBottomSize' => 0, 'borderBottomStyle' => Border::NONE])->addText("0", ['bold' => true, 'name' => 'Visby Round CF', 'size' => 9, 'color' => '#072442'], ['alignment' => Jc::CENTER]);
|
||||
$table->addCell($col5Width, ['valign' => 'center', 'bgColor' => '#f0f3fd', 'borderBottomSize' => 0, 'borderBottomStyle' => Border::NONE])->addText("56%", ['bold' => true, 'name' => 'Visby Round CF', 'size' => 9, 'color' => '#072442'], ['alignment' => Jc::CENTER]);
|
||||
|
||||
$dataTwk = ['Nasionalisme', 'Integritas', 'Bela Negara', 'Pilar Negara', 'Bahasa Indonesia', 'Bahasa Bali'];
|
||||
foreach ($dataTwk as $key => $dt) {
|
||||
$isLast = false;
|
||||
if (count($dataTwk) == $key + 1) {
|
||||
$isLast = true;
|
||||
}
|
||||
|
||||
$table->addRow();
|
||||
$table->addCell($col1Width, ['valign' => 'center', 'bgColor' => '#f0f3fd', 'borderTopSize' => 0, 'borderBottomSize' => $isLast ? 10 : 0, 'borderTopStyle' => Border::NONE, 'borderBottomStyle' => $isLast ? Border::SINGLE : Border::NONE])->addText(" " . mb_chr(8226, 'UTF-8') . " " . $dt, ['bold' => false, 'name' => 'Visby Round CF', 'size' => 8, 'color' => '#072442']);
|
||||
$table->addCell($col2Width, ['valign' => 'center', 'bgColor' => '#f0f3fd', 'borderTopSize' => 0, 'borderBottomSize' => $isLast ? 10 : 0, 'borderTopStyle' => Border::NONE, 'borderBottomStyle' => $isLast ? Border::SINGLE : Border::NONE])->addText("17", ['bold' => false, 'name' => 'Visby Round CF', 'size' => 8, 'color' => '#072442'], ['alignment' => Jc::CENTER]);
|
||||
$table->addCell($col3Width, ['valign' => 'center', 'bgColor' => '#f0f3fd', 'borderTopSize' => 0, 'borderBottomSize' => $isLast ? 10 : 0, 'borderTopStyle' => Border::NONE, 'borderBottomStyle' => $isLast ? Border::SINGLE : Border::NONE])->addText("13", ['bold' => false, 'name' => 'Visby Round CF', 'size' => 8, 'color' => '#072442'], ['alignment' => Jc::CENTER]);
|
||||
$table->addCell($col4Width, ['valign' => 'center', 'bgColor' => '#f0f3fd', 'borderTopSize' => 0, 'borderBottomSize' => $isLast ? 10 : 0, 'borderTopStyle' => Border::NONE, 'borderBottomStyle' => $isLast ? Border::SINGLE : Border::NONE])->addText("0", ['bold' => false, 'name' => 'Visby Round CF', 'size' => 8, 'color' => '#072442'], ['alignment' => Jc::CENTER]);
|
||||
$table->addCell($col5Width, ['valign' => 'center', 'bgColor' => '#f0f3fd', 'borderTopSize' => 0, 'borderBottomSize' => $isLast ? 10 : 0, 'borderTopStyle' => Border::NONE, 'borderBottomStyle' => $isLast ? Border::SINGLE : Border::NONE])->addText("56%", ['bold' => false, 'name' => 'Visby Round CF', 'size' => 8, 'color' => '#072442'], ['alignment' => Jc::CENTER]);
|
||||
}
|
||||
|
||||
$dataTkp = ['Verbal Analogi'];
|
||||
|
||||
$proc->setComplexValue('table', $table);
|
||||
|
||||
$proc->saveAs(rootPath("examples/Raport.docx"));
|
||||
|
||||
return rootPath("examples/Raport.docx");
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,8 @@
|
||||
|
||||
namespace MenulisAi\Pdfgen;
|
||||
|
||||
use MenulisAi\Pdfgen\Command\Generate;
|
||||
use MenulisAi\Pdfgen\Command\GenerateEbook;
|
||||
use MenulisAi\Pdfgen\Command\GenerateTest;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
|
||||
class Register
|
||||
@@ -13,7 +14,8 @@ class Register
|
||||
public function init(): array
|
||||
{
|
||||
return [
|
||||
new Generate("generate")
|
||||
new GenerateEbook("generate:ebook"),
|
||||
new GenerateTest("generate:test")
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
,pande,pandewidya.local,15.08.2024 10:30,file:///Users/pande/Library/Application%20Support/LibreOffice/4;
|
||||
BIN
src/Template/Doc1.docx
Normal file
BIN
src/Template/Doc1.docx
Normal file
Binary file not shown.
Binary file not shown.
BIN
src/Template/Raport.docx
Normal file
BIN
src/Template/Raport.docx
Normal file
Binary file not shown.
BIN
src/Template/Raport.odt
Normal file
BIN
src/Template/Raport.odt
Normal file
Binary file not shown.
Reference in New Issue
Block a user