mirror of
https://git.imnavajas.es/jjimenez/erp-imprimelibros.git
synced 2026-01-19 23:30:20 +00:00
preparando el imprimir
This commit is contained in:
11
src/main/java/com/imprimelibros/erp/pdf/DocumentSpec.java
Normal file
11
src/main/java/com/imprimelibros/erp/pdf/DocumentSpec.java
Normal file
@ -0,0 +1,11 @@
|
||||
package com.imprimelibros.erp.pdf;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
public record DocumentSpec(
|
||||
DocumentType type,
|
||||
String templateId, // p.ej. "presupuesto-a4"
|
||||
Locale locale,
|
||||
Map<String, Object> model // data del documento
|
||||
) {}
|
||||
@ -0,0 +1,5 @@
|
||||
package com.imprimelibros.erp.pdf;
|
||||
|
||||
public enum DocumentType {
|
||||
PRESUPUESTO, PEDIDO, FACTURA
|
||||
}
|
||||
32
src/main/java/com/imprimelibros/erp/pdf/PdfController.java
Normal file
32
src/main/java/com/imprimelibros/erp/pdf/PdfController.java
Normal file
@ -0,0 +1,32 @@
|
||||
package com.imprimelibros.erp.pdf;
|
||||
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/pdf")
|
||||
public class PdfController {
|
||||
private final PdfService pdfService;
|
||||
|
||||
public PdfController(PdfService pdfService) { this.pdfService = pdfService; }
|
||||
|
||||
@PostMapping("/{type}/{templateId}")
|
||||
public ResponseEntity<byte[]> generate(
|
||||
@PathVariable("type") DocumentType type,
|
||||
@PathVariable String templateId,
|
||||
@RequestBody Map<String,Object> model,
|
||||
Locale locale) {
|
||||
|
||||
var spec = new DocumentSpec(type, templateId, locale, model);
|
||||
var pdf = pdfService.generate(spec);
|
||||
|
||||
var fileName = type.name().toLowerCase() + "-" + templateId + ".pdf";
|
||||
return ResponseEntity.ok()
|
||||
.header("Content-Type", "application/pdf")
|
||||
.header("Content-Disposition", "inline; filename=\"" + fileName + "\"")
|
||||
.body(pdf);
|
||||
}
|
||||
}
|
||||
18
src/main/java/com/imprimelibros/erp/pdf/PdfModuleConfig.java
Normal file
18
src/main/java/com/imprimelibros/erp/pdf/PdfModuleConfig.java
Normal file
@ -0,0 +1,18 @@
|
||||
package com.imprimelibros.erp.pdf;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import java.util.Map;
|
||||
|
||||
@Configuration
|
||||
@ConfigurationProperties(prefix = "imprimelibros.pdf")
|
||||
public class PdfModuleConfig {
|
||||
/**
|
||||
* Mapa: "TYPE:templateId" -> "ruta thymeleaf" (sin extensión).
|
||||
* Ej: "PRESUPUESTO:presupuesto-a4" -> "pdf/presupuesto-a4"
|
||||
*/
|
||||
private Map<String, String> templates;
|
||||
|
||||
public Map<String, String> getTemplates() { return templates; }
|
||||
public void setTemplates(Map<String, String> templates) { this.templates = templates; }
|
||||
}
|
||||
44
src/main/java/com/imprimelibros/erp/pdf/PdfRenderer.java
Normal file
44
src/main/java/com/imprimelibros/erp/pdf/PdfRenderer.java
Normal file
@ -0,0 +1,44 @@
|
||||
package com.imprimelibros.erp.pdf;
|
||||
|
||||
import com.openhtmltopdf.pdfboxout.PdfRendererBuilder;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
|
||||
@Service
|
||||
public class PdfRenderer {
|
||||
|
||||
@Value("classpath:/static/")
|
||||
private Resource staticRoot;
|
||||
|
||||
public byte[] renderHtmlToPdf(String html) {
|
||||
try (var baos = new ByteArrayOutputStream()) {
|
||||
var builder = new PdfRendererBuilder();
|
||||
|
||||
builder.useFont(() -> getClass().getResourceAsStream("/static/assets/fonts/OpenSans-Regular.ttf"), "Open Sans",
|
||||
400, com.openhtmltopdf.outputdevice.helper.BaseRendererBuilder.FontStyle.NORMAL, true);
|
||||
builder.useFont(() -> getClass().getResourceAsStream("/static/assets/fonts/OpenSans-SemiBold.ttf"), "Open Sans",
|
||||
600, com.openhtmltopdf.outputdevice.helper.BaseRendererBuilder.FontStyle.NORMAL, true);
|
||||
builder.useFont(() -> getClass().getResourceAsStream("/static/assets/fonts/OpenSans-Bold.ttf"), "Open Sans", 700,
|
||||
com.openhtmltopdf.outputdevice.helper.BaseRendererBuilder.FontStyle.NORMAL, true);
|
||||
|
||||
builder.useFastMode();
|
||||
builder.withHtmlContent(html, baseUrl());
|
||||
builder.toStream(baos);
|
||||
builder.run();
|
||||
return baos.toByteArray();
|
||||
} catch (Exception e) {
|
||||
throw new IllegalStateException("Error generando PDF", e);
|
||||
}
|
||||
}
|
||||
|
||||
private String baseUrl() {
|
||||
try {
|
||||
return staticRoot.getURL().toString();
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
25
src/main/java/com/imprimelibros/erp/pdf/PdfService.java
Normal file
25
src/main/java/com/imprimelibros/erp/pdf/PdfService.java
Normal file
@ -0,0 +1,25 @@
|
||||
package com.imprimelibros.erp.pdf;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class PdfService {
|
||||
private final TemplateRegistry registry;
|
||||
private final PdfTemplateEngine engine;
|
||||
private final PdfRenderer renderer;
|
||||
|
||||
public PdfService(TemplateRegistry registry, PdfTemplateEngine engine, PdfRenderer renderer) {
|
||||
this.registry = registry;
|
||||
this.engine = engine;
|
||||
this.renderer = renderer;
|
||||
}
|
||||
|
||||
public byte[] generate(DocumentSpec spec) {
|
||||
var template = registry.resolve(spec.type(), spec.templateId());
|
||||
if (template == null) {
|
||||
throw new IllegalArgumentException("Plantilla no registrada: " + spec.type() + ":" + spec.templateId());
|
||||
}
|
||||
var html = engine.render(template, spec.locale(), spec.model());
|
||||
return renderer.renderHtmlToPdf(html);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,22 @@
|
||||
package com.imprimelibros.erp.pdf;
|
||||
|
||||
import org.thymeleaf.context.Context;
|
||||
import org.thymeleaf.spring6.SpringTemplateEngine;
|
||||
import org.springframework.stereotype.Service;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
@Service
|
||||
public class PdfTemplateEngine {
|
||||
private final SpringTemplateEngine thymeleaf;
|
||||
|
||||
public PdfTemplateEngine(SpringTemplateEngine thymeleaf) {
|
||||
this.thymeleaf = thymeleaf;
|
||||
}
|
||||
|
||||
public String render(String templateName, Locale locale, Map<String,Object> model) {
|
||||
Context ctx = new Context(locale);
|
||||
if (model != null) model.forEach(ctx::setVariable);
|
||||
return thymeleaf.process(templateName, ctx);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,18 @@
|
||||
// com.imprimelibros.erp.pdf.TemplateRegistry.java
|
||||
package com.imprimelibros.erp.pdf;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class TemplateRegistry {
|
||||
private final PdfModuleConfig config;
|
||||
|
||||
public TemplateRegistry(PdfModuleConfig config) {
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
public String resolve(DocumentType type, String templateId) {
|
||||
if (config.getTemplates() == null) return null;
|
||||
return config.getTemplates().get(type.name() + ":" + templateId);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user