Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
670be9a39c |
@@ -25,4 +25,20 @@ jobs:
|
||||
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
|
||||
docker rmi $(docker images -q $REGISTRY:$IMAGE_TAG) -f
|
||||
deploy:
|
||||
name: Deploy
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Pull & Restart
|
||||
uses: appleboy/ssh-action@v1.0.3
|
||||
with:
|
||||
host: ${{ secrets.SSH_VM_DEPLOYMENT_HOST }}
|
||||
key: ${{ secrets.SSH_VM_DEPLOYMENT }}
|
||||
username: ${{ secrets.SSH_VM_DEPLOYMENT_USERNAME }}
|
||||
port: ${{ secrets.SSH_VM_DEPLOYMENT_PORT }}
|
||||
script: |
|
||||
cd ~/deployment/genpdf
|
||||
docker compose pull
|
||||
docker compose down -v
|
||||
docker compose up -d
|
||||
@@ -30,7 +30,6 @@ 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
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
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
|
||||
@@ -19,7 +19,6 @@ 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
|
||||
|
||||
1
examples/.~lock.ebook_hasil.docx#
Normal file
1
examples/.~lock.ebook_hasil.docx#
Normal file
@@ -0,0 +1 @@
|
||||
,pande,pandewidya.local,15.08.2024 07:34,file:///Users/pande/Library/Application%20Support/LibreOffice/4;
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 1.8 MiB |
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
src/.DS_Store
vendored
BIN
src/.DS_Store
vendored
Binary file not shown.
@@ -10,7 +10,7 @@ use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Process\Process;
|
||||
use Symfony\Component\Process\Exception\ProcessFailedException;
|
||||
|
||||
class GenerateEbook extends Command
|
||||
class Generate extends Command
|
||||
{
|
||||
protected static $defaultName = "generate:ebook";
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
<?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,25 +2,4 @@
|
||||
|
||||
namespace MenulisAi\Pdfgen\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;
|
||||
}
|
||||
}
|
||||
interface Document {}
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace MenulisAi\Pdfgen\Document;
|
||||
|
||||
interface Documentable
|
||||
{
|
||||
public function templateSource(): string;
|
||||
public function compile(): string;
|
||||
}
|
||||
@@ -5,8 +5,10 @@ namespace MenulisAi\Pdfgen\Document;
|
||||
use PhpOffice\PhpWord\TemplateProcessor;
|
||||
use Exception;
|
||||
|
||||
class Ebook extends Document implements Documentable
|
||||
class Ebook implements Document
|
||||
{
|
||||
protected $object;
|
||||
|
||||
public function __construct(string $jsonPath)
|
||||
{
|
||||
$this->openFile($jsonPath);
|
||||
@@ -112,7 +114,21 @@ class Ebook extends Document implements Documentable
|
||||
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
|
||||
{
|
||||
|
||||
@@ -1,103 +0,0 @@
|
||||
<?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,8 +2,7 @@
|
||||
|
||||
namespace MenulisAi\Pdfgen;
|
||||
|
||||
use MenulisAi\Pdfgen\Command\GenerateEbook;
|
||||
use MenulisAi\Pdfgen\Command\GenerateTest;
|
||||
use MenulisAi\Pdfgen\Command\Generate;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
|
||||
class Register
|
||||
@@ -14,8 +13,7 @@ class Register
|
||||
public function init(): array
|
||||
{
|
||||
return [
|
||||
new GenerateEbook("generate:ebook"),
|
||||
new GenerateTest("generate:test")
|
||||
new Generate("generate:ebook")
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user