extrac prices pdfco
This commit is contained in:
parent
6b65b31932
commit
1804605cad
@ -108,9 +108,9 @@ class LoginController extends Controller
|
||||
|
||||
// Reindirizza in base al ruolo
|
||||
if ($user->hasRole('Admin')) {
|
||||
return redirect()->to('userarea/import_dashboard.php');
|
||||
return redirect()->to('userarea/import_xls.php');
|
||||
} elseif ($user->hasRole('User')) {
|
||||
return redirect()->to('userarea/import_dashboard.php');
|
||||
return redirect()->to('userarea/import_xls.php');
|
||||
}
|
||||
|
||||
// Se il ruolo non è specificato, reindirizza alla home predefinita
|
||||
|
||||
@ -47,6 +47,7 @@
|
||||
"smalot/pdfparser": "^2.12",
|
||||
"socialiteproviders/microsoft": "^4.7",
|
||||
"spatie/laravel-query-builder": "^5.0",
|
||||
"spatie/pdf-to-text": "^1.54",
|
||||
"vanguardapp/activity-log": "^6.0",
|
||||
"vanguardapp/announcements": "^6.0",
|
||||
"vanguardapp/plugins": "^6.0",
|
||||
|
||||
60
composer.lock
generated
60
composer.lock
generated
@ -4,7 +4,7 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "97382155de516648df8ab1f1c50ab1d5",
|
||||
"content-hash": "d55364bafa22e40dedff454d54442d59",
|
||||
"packages": [
|
||||
{
|
||||
"name": "akaunting/laravel-setting",
|
||||
@ -5290,6 +5290,64 @@
|
||||
],
|
||||
"time": "2024-05-10T08:19:35+00:00"
|
||||
},
|
||||
{
|
||||
"name": "spatie/pdf-to-text",
|
||||
"version": "1.54.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/spatie/pdf-to-text.git",
|
||||
"reference": "ad2a792c7e1e68f1bc9b038dc73cdcf760595fbb"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/spatie/pdf-to-text/zipball/ad2a792c7e1e68f1bc9b038dc73cdcf760595fbb",
|
||||
"reference": "ad2a792c7e1e68f1bc9b038dc73cdcf760595fbb",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.4|^8.0",
|
||||
"symfony/process": "^4.0|^5.0|^6.0|^7.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"pestphp/pest-plugin-laravel": "^1.3",
|
||||
"phpunit/phpunit": "^9.5"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Spatie\\PdfToText\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Freek Van der Herten",
|
||||
"email": "freek@spatie.be",
|
||||
"homepage": "https://spatie.be",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"description": "Extract text from a pdf",
|
||||
"homepage": "https://github.com/spatie/pdf-to-text",
|
||||
"keywords": [
|
||||
"pdf-to-text",
|
||||
"spatie"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/spatie/pdf-to-text/issues",
|
||||
"source": "https://github.com/spatie/pdf-to-text/tree/1.54.1"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://spatie.be/open-source/support-us",
|
||||
"type": "custom"
|
||||
}
|
||||
],
|
||||
"time": "2025-06-13T15:23:19+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/clock",
|
||||
"version": "v7.1.1",
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 6.0 KiB |
73
public/userarea/extract_prices.php
Normal file
73
public/userarea/extract_prices.php
Normal file
@ -0,0 +1,73 @@
|
||||
<?php
|
||||
|
||||
require_once __DIR__ . "/../../vendor/autoload.php";
|
||||
|
||||
use Spatie\PdfToText\Pdf;
|
||||
|
||||
// ---------------------------------------------------------
|
||||
// 1) Percorso PDF
|
||||
// ---------------------------------------------------------
|
||||
$pdfFile = __DIR__ . "/listino.pdf";
|
||||
|
||||
if (!file_exists($pdfFile)) {
|
||||
die(json_encode(["error" => "PDF non trovato: $pdfFile"]));
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------
|
||||
// 2) Estrazione testo usando Poppler
|
||||
// ---------------------------------------------------------
|
||||
$poppler = 'C:\poppler\Library\bin\pdftotext.exe';
|
||||
|
||||
try {
|
||||
$text = Pdf::getText($pdfFile, $poppler);
|
||||
} catch (Exception $e) {
|
||||
die(json_encode(["error" => $e->getMessage()]));
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------
|
||||
// 3) Normalizzazione
|
||||
// ---------------------------------------------------------
|
||||
$text = preg_replace('/[ ]{2,}/', ' ', $text);
|
||||
$text = str_replace("\t", " ", $text);
|
||||
|
||||
// ---------------------------------------------------------
|
||||
// 4) REGEX PER IL LISTINO CASSINA
|
||||
// ---------------------------------------------------------
|
||||
$regex = '/(\d{3}\s+\d{2,3}\s*[A-Z]?)\s+([^0-9]+?)\s+((?:\d{1,2}[.,]\d{2,3}\s+)+)/';
|
||||
|
||||
preg_match_all($regex, $text, $matches, PREG_SET_ORDER);
|
||||
|
||||
$results = [];
|
||||
|
||||
foreach ($matches as $m) {
|
||||
|
||||
$codice = trim($m[1]);
|
||||
$descr = trim($m[2]);
|
||||
$priceChunk = trim($m[3]);
|
||||
|
||||
// Trova tutti i prezzi
|
||||
preg_match_all('/\d{1,2}[.,]\d{2,3}/', $priceChunk, $nums);
|
||||
|
||||
foreach ($nums[0] as $i => $val) {
|
||||
|
||||
// 10,80 → 10.80
|
||||
$val = str_replace(',', '.', $val);
|
||||
|
||||
$results[] = [
|
||||
"codice" => $codice,
|
||||
"descrizione" => $descr,
|
||||
"colonna" => "COL_" . ($i + 1),
|
||||
"prezzo" => floatval($val)
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------
|
||||
// 5) Output JSON
|
||||
// ---------------------------------------------------------
|
||||
header("Content-Type: application/json");
|
||||
|
||||
echo json_encode([
|
||||
"items" => count($results),
|
||||
"data" => $results
|
||||
], JSON_PRETTY_PRINT);
|
||||
218
public/userarea/extract_prices_pdfco.php
Normal file
218
public/userarea/extract_prices_pdfco.php
Normal file
@ -0,0 +1,218 @@
|
||||
<?php
|
||||
header("Content-Type: application/json; charset=utf-8");
|
||||
|
||||
// ---------------------------------------------------------
|
||||
// 1) CONFIGURAZIONE
|
||||
// ---------------------------------------------------------
|
||||
$apiKey = "info@claudiosironi.com_Qfh02D7sAvi2tcx3ZchHpusNaBquCKhJw81fEnkHe2ersQDVOex4IokhCCzaFAz1";
|
||||
$fileToken = "filetoken://37bb07a8561409d281b32bcd023ff3dc33de92a8f65aae5af7";
|
||||
|
||||
// opzionale: passare un token via GET
|
||||
if (isset($_GET['token']) && $_GET['token'] !== "") {
|
||||
$fileToken = $_GET['token'];
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------
|
||||
// 2) PDF.CO → JSON2
|
||||
// ---------------------------------------------------------
|
||||
$endpoint = "https://api.pdf.co/v1/pdf/convert/to/json2";
|
||||
|
||||
$payload = [
|
||||
"url" => $fileToken,
|
||||
"inline" => true,
|
||||
"detectTables" => true,
|
||||
"pages" => ""
|
||||
];
|
||||
|
||||
$ch = curl_init($endpoint);
|
||||
curl_setopt($ch, CURLOPT_POST, true);
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, [
|
||||
"Content-Type: application/json",
|
||||
"x-api-key: $apiKey"
|
||||
]);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
|
||||
$response = curl_exec($ch);
|
||||
|
||||
if (!$response) {
|
||||
echo json_encode(["error" => "Errore CURL: " . curl_error($ch)]);
|
||||
curl_close($ch);
|
||||
exit;
|
||||
}
|
||||
|
||||
curl_close($ch);
|
||||
|
||||
$json = json_decode($response, true);
|
||||
|
||||
if (!isset($json["body"]["document"]["page"]["row"])) {
|
||||
echo json_encode([
|
||||
"error" => true,
|
||||
"message" => "JSON PDF.co non contiene tabelle utili",
|
||||
"raw" => $json
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
|
||||
$rows = $json["body"]["document"]["page"]["row"];
|
||||
|
||||
// ---------------------------------------------------------
|
||||
// 3) FUNZIONI UTILITARIE
|
||||
// ---------------------------------------------------------
|
||||
|
||||
// Formato A – 291 02F
|
||||
function isCodeTypeA($txt)
|
||||
{
|
||||
return preg_match('/^\d{3}\s+[0-9A-Z]{2,3}$/', $txt);
|
||||
}
|
||||
|
||||
// Estrai blocchi tipo "499 3A 14 5.475"
|
||||
function extractTypeCBlocks($line)
|
||||
{
|
||||
preg_match_all(
|
||||
'/(\d{3})\s+([0-9A-Z]{1,3})\s+(\d{2})\s+(\d{1,2}\.\d{3})/',
|
||||
$line,
|
||||
$m,
|
||||
PREG_SET_ORDER
|
||||
);
|
||||
|
||||
$out = [];
|
||||
foreach ($m as $b) {
|
||||
$out[] = [
|
||||
"codice" => $b[1],
|
||||
"variante" => $b[2],
|
||||
"dimensione" => $b[3],
|
||||
"prezzo" => floatval(str_replace(".", "", $b[4]))
|
||||
];
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------
|
||||
// 4) PARSER UNICO (GESTISCE TUTTI I FORMATI)
|
||||
// ---------------------------------------------------------
|
||||
$items = [];
|
||||
|
||||
$currentCode = null;
|
||||
$currentDesc = "";
|
||||
$currentPrices = [];
|
||||
|
||||
foreach ($rows as $row) {
|
||||
|
||||
// Ricostruisco la riga
|
||||
$line = "";
|
||||
foreach ($row["column"] as $col) {
|
||||
if (!isset($col["text"]["text"])) continue;
|
||||
$t = trim($col["text"]["text"]);
|
||||
if ($t !== "") $line .= " " . $t;
|
||||
}
|
||||
$line = trim($line);
|
||||
if ($line === "") continue;
|
||||
|
||||
// ---------------------------------------------------------
|
||||
// 4A — FORMATO CASSINA A (FIX prezzi concatenati)
|
||||
// ---------------------------------------------------------
|
||||
if (preg_match('/^(\d{3}\s+[0-9A-Z]{2,3})\s+(.*)$/', $line, $mA)) {
|
||||
|
||||
$codice = trim($mA[1]);
|
||||
$resto = trim($mA[2]);
|
||||
|
||||
// Estrae TUTTI i prezzi concatenati (es. "10,808.9906.460...")
|
||||
preg_match_all('/\d{1,2}[.,]\d{2,3}/', $resto, $matchesPrezzi);
|
||||
|
||||
if (count($matchesPrezzi[0]) >= 2) {
|
||||
|
||||
// Descrizione SENZA prezzi
|
||||
$descr = trim(preg_replace('/\d{1,2}[.,]\d{2,3}/', '', $resto));
|
||||
|
||||
// Conversione valori
|
||||
$vals = array_map(function ($v) {
|
||||
return floatval(str_replace(",", ".", str_replace(".", "", $v)));
|
||||
}, $matchesPrezzi[0]);
|
||||
|
||||
$items[] = [
|
||||
"type" => "A",
|
||||
"codice" => $codice,
|
||||
"descrizione" => $descr,
|
||||
"prezzi" => $vals
|
||||
];
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------
|
||||
// 4B — FORMATO VECCHIO CASSINA (003 BC cromata … 8 prezzi)
|
||||
// ---------------------------------------------------------
|
||||
if (preg_match(
|
||||
'/^(\d{3}\s+[A-Z]{1,3})\s+([A-Za-zÀ-ù\s]+?)\s+((?:\d{1,2}[.,]\d{2,3}\s*){8,})$/',
|
||||
$line,
|
||||
$mB
|
||||
)) {
|
||||
$codice = trim($mB[1]);
|
||||
$descr = trim($mB[2]);
|
||||
$valuesString = trim($mB[3]);
|
||||
|
||||
preg_match_all('/\d{1,2}[.,]\d{2,3}/', $valuesString, $vv);
|
||||
|
||||
$vals = array_map(function ($v) {
|
||||
return floatval(str_replace(",", ".", str_replace(".", "", $v)));
|
||||
}, $vv[0]);
|
||||
|
||||
$categorie = ["Z", "Y", "X", "O", "L", "F/COL", "E/COM", "ALTRO"];
|
||||
|
||||
$prezziMappati = [];
|
||||
foreach ($vals as $i => $v) {
|
||||
$key = $categorie[$i] ?? ("COL_" . ($i + 1));
|
||||
$prezziMappati[$key] = $v;
|
||||
}
|
||||
|
||||
$items[] = [
|
||||
"type" => "B1",
|
||||
"codice" => $codice,
|
||||
"descrizione" => $descr,
|
||||
"prezzi" => $prezziMappati
|
||||
];
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------
|
||||
// 4C — FORMATO LISTINO2 (499 3A 14 5.475 ripetuti)
|
||||
// ---------------------------------------------------------
|
||||
$blocks = extractTypeCBlocks($line);
|
||||
|
||||
if (!empty($blocks)) {
|
||||
|
||||
$desc = $line;
|
||||
foreach ($blocks as $b) {
|
||||
$pattern = sprintf(
|
||||
'/%s\s+%s\s+%s\s+\d{1,2}\.\d{3}/',
|
||||
$b["codice"],
|
||||
$b["variante"],
|
||||
$b["dimensione"]
|
||||
);
|
||||
$desc = preg_replace($pattern, "", $desc);
|
||||
}
|
||||
|
||||
$desc = trim($desc);
|
||||
|
||||
$items[] = [
|
||||
"type" => "C",
|
||||
"descrizione" => $desc,
|
||||
"varianti" => $blocks
|
||||
];
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------
|
||||
// 5) OUTPUT FINALE
|
||||
// ---------------------------------------------------------
|
||||
echo json_encode([
|
||||
"status" => "ok",
|
||||
"total" => count($items),
|
||||
"items" => $items
|
||||
], JSON_PRETTY_PRINT);
|
||||
137
public/userarea/extract_prices_table.php
Normal file
137
public/userarea/extract_prices_table.php
Normal file
@ -0,0 +1,137 @@
|
||||
<?php
|
||||
header("Content-Type: application/json; charset=utf-8");
|
||||
|
||||
/******************************************************
|
||||
* CONFIG
|
||||
******************************************************/
|
||||
$apiKey = "info@claudiosironi.com_Qfh02D7sAvi2tcx3ZchHpusNaBquCKhJw81fEnkHe2ersQDVOex4IokhCCzaFAz1";
|
||||
$fileToken = "filetoken://61a780917907f86a340290d22c449357dc68950e9066bd67b2";
|
||||
|
||||
// Se passi ?token=xxx usa quello
|
||||
if (!empty($_GET['token'])) {
|
||||
$fileToken = $_GET['token'];
|
||||
}
|
||||
|
||||
/******************************************************
|
||||
* 1) ESTRAGGO CSV (solo pagine con tabelle vere)
|
||||
******************************************************/
|
||||
$endpointCsv = "https://api.pdf.co/v1/pdf/convert/to/csv";
|
||||
|
||||
$payloadCsv = [
|
||||
"url" => $fileToken,
|
||||
"inline" => true,
|
||||
"detectTables" => true,
|
||||
"pages" => "all",
|
||||
"extractColumnBy" => "vertical_lines",
|
||||
"csvSeparator" => ";"
|
||||
];
|
||||
|
||||
$ch = curl_init($endpointCsv);
|
||||
curl_setopt($ch, CURLOPT_POST, true);
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, [
|
||||
"Content-Type: application/json",
|
||||
"x-api-key: $apiKey"
|
||||
]);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payloadCsv));
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
|
||||
$csvResponse = curl_exec($ch);
|
||||
curl_close($ch);
|
||||
|
||||
$csvJson = json_decode($csvResponse, true);
|
||||
|
||||
/******************************************************
|
||||
* 2) ESTRAGGO ANCHE TESTO (per pagine NON tabellari)
|
||||
******************************************************/
|
||||
$endpointText = "https://api.pdf.co/v1/pdf/convert/to/text";
|
||||
|
||||
$payloadText = [
|
||||
"url" => $fileToken,
|
||||
"inline" => true,
|
||||
"pages" => "all"
|
||||
];
|
||||
|
||||
$ch = curl_init($endpointText);
|
||||
curl_setopt($ch, CURLOPT_POST, true);
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, [
|
||||
"Content-Type: application/json",
|
||||
"x-api-key: $apiKey"
|
||||
]);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payloadText));
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
|
||||
$textResponse = curl_exec($ch);
|
||||
curl_close($ch);
|
||||
|
||||
$textJson = json_decode($textResponse, true);
|
||||
|
||||
/******************************************************
|
||||
* 3) PARSER CSV → TABELLE FORMATO A
|
||||
******************************************************/
|
||||
$formatoA = [];
|
||||
|
||||
if (isset($csvJson["csv"])) {
|
||||
$rows = explode("\n", $csvJson["csv"]);
|
||||
|
||||
foreach ($rows as $r) {
|
||||
$cols = str_getcsv($r, ";");
|
||||
|
||||
if (count($cols) < 2) continue;
|
||||
if (!preg_match('/^\d{3}\s+[0-9A-Z]{2,3}$/', trim($cols[0]))) continue;
|
||||
|
||||
$formatoA[] = [
|
||||
"codice" => trim($cols[0]),
|
||||
"descrizione" => trim($cols[1]),
|
||||
"prezzi" => array_map(fn($x) => is_numeric(str_replace(",", ".", $x))
|
||||
? floatval(str_replace(",", ".", $x))
|
||||
: null, array_slice($cols, 2))
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************
|
||||
* 4) PARSER TESTUALE → FORMATO B (pagina tipo 499…)
|
||||
******************************************************/
|
||||
$formatoB = [];
|
||||
|
||||
if (isset($textJson["body"])) {
|
||||
|
||||
$text = $textJson["body"];
|
||||
|
||||
// pattern codice tipo “499 3A 14”
|
||||
$codeRegex = '/\b(\d{3}\s+[A-Z0-9]{1,2}\s+\d{2})\b/';
|
||||
|
||||
// pattern prezzo “5.475” o “5475” o “6.085”
|
||||
$priceRegex = '/\b\d{1,2}\.?\d{3}\b/';
|
||||
|
||||
// Cerca combinazioni CODICE + PREZZO ripetute sulla stessa riga
|
||||
$linee = explode("\n", $text);
|
||||
|
||||
foreach ($linee as $line) {
|
||||
|
||||
if (!preg_match_all($codeRegex, $line, $codici)) continue;
|
||||
if (!preg_match_all($priceRegex, $line, $prezzi)) continue;
|
||||
|
||||
$codici = $codici[1];
|
||||
$prezzi = $prezzi[0];
|
||||
|
||||
// Se quantità corrispondono → coppie 1:1
|
||||
if (count($codici) == count($prezzi)) {
|
||||
for ($i = 0; $i < count($codici); $i++) {
|
||||
$formatoB[] = [
|
||||
"codice" => $codici[$i],
|
||||
"prezzo" => floatval(str_replace(".", "", $prezzi[$i]))
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************
|
||||
* 5) OUTPUT
|
||||
******************************************************/
|
||||
echo json_encode([
|
||||
"status" => "ok",
|
||||
"formatoA" => $formatoA,
|
||||
"formatoB" => $formatoB,
|
||||
], JSON_PRETTY_PRINT);
|
||||
@ -45,6 +45,7 @@ $pdo = $db->getConnection();
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="wrapper">
|
||||
<?php include('include/navbar.php'); ?>
|
||||
<div class="dashboard-main-wrapper wrapper">
|
||||
<?php include('include/topbar.php'); ?>
|
||||
@ -382,20 +383,30 @@ $pdo = $db->getConnection();
|
||||
},
|
||||
success: function(res) {
|
||||
Swal.close();
|
||||
let json;
|
||||
|
||||
// Se il server ha già restituito un oggetto JSON, usiamolo direttamente
|
||||
let json = (typeof res === "object") ? res : null;
|
||||
|
||||
// Se invece è una stringa JSON, parse
|
||||
if (!json) {
|
||||
try {
|
||||
json = JSON.parse(res);
|
||||
} catch (e) {
|
||||
Swal.fire('Errore', res, 'error');
|
||||
console.error("JSON parse error:", res);
|
||||
Swal.fire('Errore', 'Risposta non valida dal server.', 'error');
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Ora siamo sicuri che json è un oggetto valido
|
||||
if (json.status === 'ok') {
|
||||
Swal.fire('Successo', `Aggiornati ${json.updated} prezzi.`, 'success');
|
||||
table.ajax.reload(null, false);
|
||||
} else {
|
||||
Swal.fire('Errore', json.message, 'error');
|
||||
Swal.fire('Errore', json.message || 'Errore sconosciuto.', 'error');
|
||||
}
|
||||
},
|
||||
|
||||
error: function() {
|
||||
Swal.fire('Errore', 'Aggiornamento fallito.', 'error');
|
||||
}
|
||||
@ -407,6 +418,7 @@ $pdo = $db->getConnection();
|
||||
|
||||
});
|
||||
</script>
|
||||
</div> <!-- end wrapper -->
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@ -22,9 +22,10 @@
|
||||
<ul>
|
||||
<!-- <li> <a href="index.php"><i class='bx bx-radio-circle'></i>Default</a>
|
||||
</li> -->
|
||||
<li> <a href="import_dashboard.php"><i class='bx bx-radio-circle'></i>XLS Import</a>
|
||||
<li> <a href="import_xls.php"><i class='bx bx-radio-circle'></i>XLS Import</a>
|
||||
</li>
|
||||
<li> <a href="import_list.php"><i class='bx bx-radio-circle'></i>Imported LIST</a>
|
||||
</li>
|
||||
|
||||
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
217
public/userarea/jsonraw.php
Normal file
217
public/userarea/jsonraw.php
Normal file
@ -0,0 +1,217 @@
|
||||
<?php
|
||||
header("Content-Type: application/json; charset=utf-8");
|
||||
|
||||
// ---------------------------------------------------------
|
||||
// 1) CONFIGURAZIONE
|
||||
// ---------------------------------------------------------
|
||||
$apiKey = "info@claudiosironi.com_Qfh02D7sAvi2tcx3ZchHpusNaBquCKhJw81fEnkHe2ersQDVOex4IokhCCzaFAz1";
|
||||
$fileToken = "filetoken://61a780917907f86a340290d22c449357dc68950e9066bd67b2";
|
||||
|
||||
// opzionale: passare un token via GET
|
||||
if (isset($_GET['token']) && $_GET['token'] !== "") {
|
||||
$fileToken = $_GET['token'];
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------
|
||||
// 2) PDF.CO → JSON2 (TUTTE LE PAGINE)
|
||||
// ---------------------------------------------------------
|
||||
$endpoint = "https://api.pdf.co/v1/pdf/convert/to/json2";
|
||||
|
||||
$payload = [
|
||||
"url" => $fileToken,
|
||||
"inline" => true,
|
||||
"detectTables" => true,
|
||||
"pages" => "all"
|
||||
];
|
||||
|
||||
$ch = curl_init($endpoint);
|
||||
curl_setopt($ch, CURLOPT_POST, true);
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, [
|
||||
"Content-Type: application/json",
|
||||
"x-api-key: $apiKey"
|
||||
]);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
|
||||
$response = curl_exec($ch);
|
||||
|
||||
if (!$response) {
|
||||
echo json_encode(["error" => "Errore CURL: " . curl_error($ch)]);
|
||||
exit;
|
||||
}
|
||||
|
||||
curl_close($ch);
|
||||
|
||||
$json = json_decode($response, true);
|
||||
|
||||
// ---------------------------------------------------------
|
||||
// 3) VALIDAZIONE
|
||||
// ---------------------------------------------------------
|
||||
if (!isset($json["body"]["document"]["page"])) {
|
||||
echo json_encode([
|
||||
"error" => true,
|
||||
"message" => "PDF.co JSON senza pagine valide",
|
||||
"raw" => $json
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
|
||||
$pages = $json["body"]["document"]["page"];
|
||||
|
||||
// ---------------------------------------------------------
|
||||
// 4) FUNZIONI UTILI
|
||||
// ---------------------------------------------------------
|
||||
|
||||
// Formato A – 291 02F
|
||||
function isCodeTypeA($txt)
|
||||
{
|
||||
return preg_match('/^\d{3}\s+[0-9A-Z]{2,3}$/', $txt);
|
||||
}
|
||||
|
||||
// Formato C – blocchi ripetuti (499 3A 14 5.475)
|
||||
function extractTypeCBlocks($line)
|
||||
{
|
||||
preg_match_all(
|
||||
'/(\d{3})\s+([0-9A-Z]{1,3})\s+(\d{2})\s+(\d{1,3}\.\d{3})/',
|
||||
$line,
|
||||
$m,
|
||||
PREG_SET_ORDER
|
||||
);
|
||||
|
||||
$out = [];
|
||||
foreach ($m as $b) {
|
||||
$out[] = [
|
||||
"codice" => $b[1],
|
||||
"variante" => $b[2],
|
||||
"dimensione" => $b[3],
|
||||
"prezzo" => floatval(str_replace(".", "", $b[4]))
|
||||
];
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------
|
||||
// 5) PARSER PER UNA SINGOLA RIGA (ricostruita)
|
||||
// ---------------------------------------------------------
|
||||
function parseLine($line)
|
||||
{
|
||||
// FORMATO A
|
||||
if (preg_match('/^(\d{3}\s+[0-9A-Z]{2,3})\s+(.*)$/', $line, $mA)) {
|
||||
|
||||
$codice = trim($mA[1]);
|
||||
$resto = trim($mA[2]);
|
||||
|
||||
preg_match_all('/\d{1,3}[.,]\d{2,3}/', $resto, $matchesPrezzi);
|
||||
|
||||
if (count($matchesPrezzi[0]) >= 2) {
|
||||
|
||||
$descr = trim(preg_replace('/\d{1,3}[.,]\d{2,3}/', '', $resto));
|
||||
|
||||
$vals = array_map(function ($v) {
|
||||
return floatval(str_replace(",", ".", str_replace(".", "", $v)));
|
||||
}, $matchesPrezzi[0]);
|
||||
|
||||
return [
|
||||
"type" => "A",
|
||||
"codice" => $codice,
|
||||
"descrizione" => $descr,
|
||||
"prezzi" => $vals
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
// FORMATO B1
|
||||
if (preg_match(
|
||||
'/^(\d{3}\s+[A-Z]{1,3})\s+([A-Za-zÀ-ù0-9\s]+?)\s+((?:\d{1,3}[.,]\d{2,3}\s*){4,})$/',
|
||||
$line,
|
||||
$mB
|
||||
)) {
|
||||
$codice = trim($mB[1]);
|
||||
$descr = trim($mB[2]);
|
||||
$valuesString = trim($mB[3]);
|
||||
|
||||
preg_match_all('/\d{1,3}[.,]\d{2,3}/', $valuesString, $vv);
|
||||
|
||||
$vals = array_map(function ($v) {
|
||||
return floatval(str_replace(",", ".", str_replace(".", "", $v)));
|
||||
}, $vv[0]);
|
||||
|
||||
return [
|
||||
"type" => "B1",
|
||||
"codice" => $codice,
|
||||
"descrizione" => $descr,
|
||||
"prezzi" => $vals
|
||||
];
|
||||
}
|
||||
|
||||
// FORMATO C (ripetuto in riga)
|
||||
$blocks = extractTypeCBlocks($line);
|
||||
|
||||
if (!empty($blocks)) {
|
||||
|
||||
$desc = $line;
|
||||
foreach ($blocks as $b) {
|
||||
$pattern = sprintf(
|
||||
'/%s\s+%s\s+%s\s+\d{1,3}\.\d{3}/',
|
||||
$b["codice"],
|
||||
$b["variante"],
|
||||
$b["dimensione"]
|
||||
);
|
||||
$desc = preg_replace($pattern, "", $desc);
|
||||
}
|
||||
|
||||
$desc = trim($desc);
|
||||
|
||||
return [
|
||||
"type" => "C",
|
||||
"descrizione" => $desc,
|
||||
"varianti" => $blocks
|
||||
];
|
||||
}
|
||||
|
||||
// Nessun match
|
||||
return null;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------
|
||||
// 6) PROCESSAMENTO DI TUTTE LE PAGINE
|
||||
// ---------------------------------------------------------
|
||||
$items = [];
|
||||
|
||||
foreach ($pages as $p) {
|
||||
|
||||
if (!isset($p["row"])) continue;
|
||||
|
||||
// Ricostruisco tutte le vere righe (“flat lines”)
|
||||
$flatLines = [];
|
||||
|
||||
foreach ($p["row"] as $row) {
|
||||
$line = "";
|
||||
foreach ($row["column"] as $col) {
|
||||
if (!empty($col["text"]["text"])) {
|
||||
$line .= " " . trim($col["text"]["text"]);
|
||||
}
|
||||
}
|
||||
$line = trim($line);
|
||||
if ($line !== "") {
|
||||
$flatLines[] = $line;
|
||||
}
|
||||
}
|
||||
|
||||
// Applico i parser su ogni riga ricostruita
|
||||
foreach ($flatLines as $l) {
|
||||
$parsed = parseLine($l);
|
||||
if ($parsed !== null) {
|
||||
$items[] = $parsed;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------
|
||||
// 7) OUTPUT FINALE
|
||||
// ---------------------------------------------------------
|
||||
echo json_encode([
|
||||
"status" => "ok",
|
||||
"total" => count($items),
|
||||
"items" => $items
|
||||
], JSON_PRETTY_PRINT);
|
||||
BIN
public/userarea/listino.pdf
Normal file
BIN
public/userarea/listino.pdf
Normal file
Binary file not shown.
4
vendor/composer/autoload_classmap.php
vendored
4
vendor/composer/autoload_classmap.php
vendored
@ -6660,6 +6660,10 @@ return array(
|
||||
'Spatie\\LaravelPackageTools\\Exceptions\\InvalidPackage' => $vendorDir . '/spatie/laravel-package-tools/src/Exceptions/InvalidPackage.php',
|
||||
'Spatie\\LaravelPackageTools\\Package' => $vendorDir . '/spatie/laravel-package-tools/src/Package.php',
|
||||
'Spatie\\LaravelPackageTools\\PackageServiceProvider' => $vendorDir . '/spatie/laravel-package-tools/src/PackageServiceProvider.php',
|
||||
'Spatie\\PdfToText\\Exceptions\\BinaryNotFoundException' => $vendorDir . '/spatie/pdf-to-text/src/Exceptions/BinaryNotFoundException.php',
|
||||
'Spatie\\PdfToText\\Exceptions\\CouldNotExtractText' => $vendorDir . '/spatie/pdf-to-text/src/Exceptions/CouldNotExtractText.php',
|
||||
'Spatie\\PdfToText\\Exceptions\\PdfNotFound' => $vendorDir . '/spatie/pdf-to-text/src/Exceptions/PdfNotFound.php',
|
||||
'Spatie\\PdfToText\\Pdf' => $vendorDir . '/spatie/pdf-to-text/src/Pdf.php',
|
||||
'Spatie\\QueryBuilder\\AllowedFilter' => $vendorDir . '/spatie/laravel-query-builder/src/AllowedFilter.php',
|
||||
'Spatie\\QueryBuilder\\AllowedInclude' => $vendorDir . '/spatie/laravel-query-builder/src/AllowedInclude.php',
|
||||
'Spatie\\QueryBuilder\\AllowedSort' => $vendorDir . '/spatie/laravel-query-builder/src/AllowedSort.php',
|
||||
|
||||
1
vendor/composer/autoload_psr4.php
vendored
1
vendor/composer/autoload_psr4.php
vendored
@ -54,6 +54,7 @@ return array(
|
||||
'Symfony\\Component\\Clock\\' => array($vendorDir . '/symfony/clock'),
|
||||
'Spatie\\QueryBuilder\\Database\\Factories\\' => array($vendorDir . '/spatie/laravel-query-builder/database/factories'),
|
||||
'Spatie\\QueryBuilder\\' => array($vendorDir . '/spatie/laravel-query-builder/src'),
|
||||
'Spatie\\PdfToText\\' => array($vendorDir . '/spatie/pdf-to-text/src'),
|
||||
'Spatie\\LaravelPackageTools\\' => array($vendorDir . '/spatie/laravel-package-tools/src'),
|
||||
'Spatie\\LaravelIgnition\\' => array($vendorDir . '/spatie/laravel-ignition/src', $vendorDir . '/spatie/error-solutions/legacy/laravel-ignition'),
|
||||
'Spatie\\Ignition\\' => array($vendorDir . '/spatie/ignition/src', $vendorDir . '/spatie/error-solutions/legacy/ignition'),
|
||||
|
||||
9
vendor/composer/autoload_static.php
vendored
9
vendor/composer/autoload_static.php
vendored
@ -114,6 +114,7 @@ class ComposerStaticInitc91cd9c5b1e6a9e8573a14b799ea9342
|
||||
'Symfony\\Component\\Clock\\' => 24,
|
||||
'Spatie\\QueryBuilder\\Database\\Factories\\' => 39,
|
||||
'Spatie\\QueryBuilder\\' => 20,
|
||||
'Spatie\\PdfToText\\' => 17,
|
||||
'Spatie\\LaravelPackageTools\\' => 27,
|
||||
'Spatie\\LaravelIgnition\\' => 23,
|
||||
'Spatie\\Ignition\\' => 16,
|
||||
@ -440,6 +441,10 @@ class ComposerStaticInitc91cd9c5b1e6a9e8573a14b799ea9342
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/spatie/laravel-query-builder/src',
|
||||
),
|
||||
'Spatie\\PdfToText\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/spatie/pdf-to-text/src',
|
||||
),
|
||||
'Spatie\\LaravelPackageTools\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/spatie/laravel-package-tools/src',
|
||||
@ -7483,6 +7488,10 @@ class ComposerStaticInitc91cd9c5b1e6a9e8573a14b799ea9342
|
||||
'Spatie\\LaravelPackageTools\\Exceptions\\InvalidPackage' => __DIR__ . '/..' . '/spatie/laravel-package-tools/src/Exceptions/InvalidPackage.php',
|
||||
'Spatie\\LaravelPackageTools\\Package' => __DIR__ . '/..' . '/spatie/laravel-package-tools/src/Package.php',
|
||||
'Spatie\\LaravelPackageTools\\PackageServiceProvider' => __DIR__ . '/..' . '/spatie/laravel-package-tools/src/PackageServiceProvider.php',
|
||||
'Spatie\\PdfToText\\Exceptions\\BinaryNotFoundException' => __DIR__ . '/..' . '/spatie/pdf-to-text/src/Exceptions/BinaryNotFoundException.php',
|
||||
'Spatie\\PdfToText\\Exceptions\\CouldNotExtractText' => __DIR__ . '/..' . '/spatie/pdf-to-text/src/Exceptions/CouldNotExtractText.php',
|
||||
'Spatie\\PdfToText\\Exceptions\\PdfNotFound' => __DIR__ . '/..' . '/spatie/pdf-to-text/src/Exceptions/PdfNotFound.php',
|
||||
'Spatie\\PdfToText\\Pdf' => __DIR__ . '/..' . '/spatie/pdf-to-text/src/Pdf.php',
|
||||
'Spatie\\QueryBuilder\\AllowedFilter' => __DIR__ . '/..' . '/spatie/laravel-query-builder/src/AllowedFilter.php',
|
||||
'Spatie\\QueryBuilder\\AllowedInclude' => __DIR__ . '/..' . '/spatie/laravel-query-builder/src/AllowedInclude.php',
|
||||
'Spatie\\QueryBuilder\\AllowedSort' => __DIR__ . '/..' . '/spatie/laravel-query-builder/src/AllowedSort.php',
|
||||
|
||||
61
vendor/composer/installed.json
vendored
61
vendor/composer/installed.json
vendored
@ -8827,6 +8827,67 @@
|
||||
],
|
||||
"install-path": "../spatie/laravel-query-builder"
|
||||
},
|
||||
{
|
||||
"name": "spatie/pdf-to-text",
|
||||
"version": "1.54.1",
|
||||
"version_normalized": "1.54.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/spatie/pdf-to-text.git",
|
||||
"reference": "ad2a792c7e1e68f1bc9b038dc73cdcf760595fbb"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/spatie/pdf-to-text/zipball/ad2a792c7e1e68f1bc9b038dc73cdcf760595fbb",
|
||||
"reference": "ad2a792c7e1e68f1bc9b038dc73cdcf760595fbb",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.4|^8.0",
|
||||
"symfony/process": "^4.0|^5.0|^6.0|^7.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"pestphp/pest-plugin-laravel": "^1.3",
|
||||
"phpunit/phpunit": "^9.5"
|
||||
},
|
||||
"time": "2025-06-13T15:23:19+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Spatie\\PdfToText\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Freek Van der Herten",
|
||||
"email": "freek@spatie.be",
|
||||
"homepage": "https://spatie.be",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"description": "Extract text from a pdf",
|
||||
"homepage": "https://github.com/spatie/pdf-to-text",
|
||||
"keywords": [
|
||||
"pdf-to-text",
|
||||
"spatie"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/spatie/pdf-to-text/issues",
|
||||
"source": "https://github.com/spatie/pdf-to-text/tree/1.54.1"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://spatie.be/open-source/support-us",
|
||||
"type": "custom"
|
||||
}
|
||||
],
|
||||
"install-path": "../spatie/pdf-to-text"
|
||||
},
|
||||
{
|
||||
"name": "symfony/clock",
|
||||
"version": "v7.1.1",
|
||||
|
||||
13
vendor/composer/installed.php
vendored
13
vendor/composer/installed.php
vendored
@ -3,7 +3,7 @@
|
||||
'name' => 'loshmis/vanguard',
|
||||
'pretty_version' => 'dev-main',
|
||||
'version' => 'dev-main',
|
||||
'reference' => 'e75be99e43b28088315b19f86eee2e6869c7c844',
|
||||
'reference' => '6b65b31932e62bc55f5c539e7856ca8eb8440782',
|
||||
'type' => 'project',
|
||||
'install_path' => __DIR__ . '/../../',
|
||||
'aliases' => array(),
|
||||
@ -688,7 +688,7 @@
|
||||
'loshmis/vanguard' => array(
|
||||
'pretty_version' => 'dev-main',
|
||||
'version' => 'dev-main',
|
||||
'reference' => 'e75be99e43b28088315b19f86eee2e6869c7c844',
|
||||
'reference' => '6b65b31932e62bc55f5c539e7856ca8eb8440782',
|
||||
'type' => 'project',
|
||||
'install_path' => __DIR__ . '/../../',
|
||||
'aliases' => array(),
|
||||
@ -1391,6 +1391,15 @@
|
||||
0 => '*',
|
||||
),
|
||||
),
|
||||
'spatie/pdf-to-text' => array(
|
||||
'pretty_version' => '1.54.1',
|
||||
'version' => '1.54.1.0',
|
||||
'reference' => 'ad2a792c7e1e68f1bc9b038dc73cdcf760595fbb',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../spatie/pdf-to-text',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/clock' => array(
|
||||
'pretty_version' => 'v7.1.1',
|
||||
'version' => '7.1.1.0',
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user