Browse Source

Create document using LibreOffice

master
Alex Puiu 2 years ago
parent
commit
fce31deabd
  1. 58
      app/Http/Controllers/FileController.php
  2. 12
      resources/js/components/ProcessFile/ProcessFile.ts
  3. 5
      resources/js/services/ApiService.ts
  4. 8
      routes/web.php

58
app/Http/Controllers/FileController.php

@ -7,8 +7,8 @@ use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Storage;
use Illuminate\Http\UploadedFile;
use GuzzleHttp\Exception\BadResponseException;
use App\SearchDisplace\SearchAndDisplace;
use Symfony\Component\Process\Process;
use Symfony\Component\Process\Exception\ProcessFailedException;
class FileController extends Controller
{
@ -41,6 +41,15 @@ class FileController extends Controller
'name' => $file->getClientOriginalName()
]);
$originalFile = $fileId . "/{$fileId}." . $file->extension();
Storage::disk('local')->put("contracts/{$originalFile}", file_get_contents($file)); // keep the original file
$process = new Process(['soffice', '--convert-to', 'xml', storage_path('app/contracts/' . $originalFile), '--outdir', storage_path('app/contracts/') . $fileId]);
$process->run();
Storage::delete("contracts/{$originalFile}");
return response()->json([
'id' => $fileId,
'file_name' => $file->getClientOriginalName(),
@ -62,26 +71,38 @@ class FileController extends Controller
*/
public function convert(): JsonResponse
{
$mdFileContent = request()->input('content');
$fileId = request()->input('file_id');
$searchers = request()->input('searchers');
Storage::disk('local')->put('tmp/' . $fileId . '.md', $mdFileContent);
$tmpFilePath = Storage::path('tmp/' . $fileId);
$process = new Process(['pandoc', '-f', 'markdown_strict', $tmpFilePath . '.md', '-t', 'html']);
$process->run();
if (!$process->isSuccessful()) {
throw new ProcessFailedException($process);
$xml = storage_path() . "/app/contracts/{$fileId}/{$fileId}.xml";
$dom = new \DOMDocument();
$dom->load($xml);
foreach($dom->getElementsByTagName('p') as $key => $text) {
$is_image = false;
if($text->childNodes) {
foreach($text->childNodes as $child) {
if(isset($child->tagName) && $child->tagName == 'draw:frame') {
$is_image = true;
}
}
}
if(!$is_image) {
$searchAndDisplace = new SearchAndDisplace(
stripslashes($text->textContent),
[
'searchers' => $searchers,
]
);
$response = $searchAndDisplace->execute();
$text->textContent = $response['content'];
}
}
$output = str_replace('./contracts-images', config('app.url') . '/contracts-images', $process->getOutput());
Storage::disk('local')->put('tmp/' . $fileId . '.html', $output);
$process = new Process([ 'pandoc', '-f', 'html', $tmpFilePath . '.html', '-t', 'odt', '-o', $tmpFilePath . '.odt']);
$dom->save($xml);
$process = new Process(['soffice', '--convert-to', 'odt', $xml, '--outdir', storage_path('app/tmp/')]);
$process->run();
if (!$process->isSuccessful()) {
throw new ProcessFailedException($process);
}
return response()->json([
'path' => 'tmp/' . $fileId . '.odt'
@ -107,10 +128,7 @@ class FileController extends Controller
public function delete(string $id): JsonResponse
{
$success = Storage::delete([
"tmp/{$id}.md",
"tmp/{$id}.odt",
"tmp/{$id}.html",
"contracts/{$id}.md",
"tmp/{$id}.odt"
]);
return response()->json(['success' => $success]);
}

12
resources/js/components/ProcessFile/ProcessFile.ts

@ -418,7 +418,17 @@ export default class ProcessFile extends Vue {
* Download the document in ODT format
*/
private async downloadOdt() {
let response = await this.$api.convertFile(this.processedFileContent, this.file.id);
let searchers: Array<{ key: string; type: string; value: string; }> = [];
Object.values(this.selectedSearchers).forEach((searcher: any) => {
searchers.push({
key: searcher.id,
type: this.searchersOptions[searcher.id].type,
value: this.searchersOptions[searcher.id].value || '',
});
});
let response = await this.$api.convertFile(this.processedFileContent, this.file.id, searchers);
window.open(`${window.location.origin}/file/download/` + response.path);
}

5
resources/js/services/ApiService.ts

@ -145,13 +145,14 @@ export default class ApiService {
*
* @returns
*/
public async convertFile(content: string, fileId: string) {
public async convertFile(content: string, fileId: string, searchers: Array<{ key: string; type: string; value: string; }>) {
try {
let response = await axios.post(
this.apiRoutes.fileDownload,
{
'file_id': fileId,
'content': content
'content': content,
'searchers': searchers
}
);

8
routes/web.php

@ -15,6 +15,14 @@ use Illuminate\Support\Facades\Route;
*/
Route::get('/', 'HomeController@index');
// Route::get('/', function() {
// $dom = new DOMDocument();
// $dom->load(storage_path() . '/doc.xml');
// $dom->getElementsByTagName('p')->item(0)->nodeValue = 'changed';
// $dom->save(storage_path() . '/changed.xml');
// });
Route::get('/file/download/{path}', [
FileController::class,

Loading…
Cancel
Save