Spring Boot Html to Image (Html Rendering) - spring

I am using spring boot and want to create Image from Html
I am using SpringTemplateEngine and ClassLoaderTemplateResolver to get rendered html But when I am creating the image, the css is not Applied on it.
I also have to replace images in html, so it's necessary to render html.
Below is my code, any help will be highly appreciated
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
ClassLoaderTemplateResolver templateResolver = new ClassLoaderTemplateResolver();
templateResolver.setPrefix("templates/");
templateResolver.setCacheable(false);
templateResolver.setSuffix(".html");
templateResolver.setTemplateMode("HTML");
templateEngine.setTemplateResolver(templateResolver);
Context ctx = new Context();
SimpleDateFormat dateFormat = new SimpleDateFormat("dd MMMM yyyy");
Calendar cal = Calendar.getInstance();
ctx.setVariable("todayDate", dateFormat.format(cal.getTime()));
ctx.setVariable("name", "Manoj");
final String result = templateEngine.process("index", ctx);
System.out.println("result:" + result);
// Change the image type to demonstrate that GIF and PNG still work properly
String fileType = "png";
HtmlImageGenerator originalGenerator = new HtmlImageGenerator();
originalGenerator.loadHtml(result);
originalGenerator.saveAsImage("cards/original" + "_" + fileType + "." + fileType);

Related

read json file from resources

I'm trying to read json file that located in documents folder into resources file in quarkus.
here is my code:
try(InputStream inputStream = classLoader.getResourceAsStream("documents/helloWorldDocument.json")) {
// Retrieve the JSON document and put into a string/object map
ObjectMapper mapper = new ObjectMapper();
TypeReference<HashMap<String, Object>> documentMapType =
new TypeReference<HashMap<String, Object>>() {};
//
Map<String, Object> document = mapper.readValue(
new File(inputStream.toString()),
documentMapType);
// Use builder methods in the SDK to create the directive.
RenderDocumentDirective renderDocumentDirective = RenderDocumentDirective.builder()
.withToken("helloWorldToken")
.withDocument(document)
.build();
// Add the directive to a responseBuilder.
responseBuilder.addDirective(renderDocumentDirective);
// Tailor the speech for a device with a screen.
speechText.append(" You should now also see my greeting on the screen.");
} catch (IOException e) {
throw new AskSdkException("Unable to read or deserialize the hello world document", e);
}
but getting exception. really appreciate if anyone could help.
(I'm implementing APL for an alexa skill)
After searching a lot, I solve this:
try {
File file = new File(
Objects.requireNonNull(this.getClass().getClassLoader().getResource("helloWorldDocument.json")).getFile()
);
ObjectMapper mapper = new ObjectMapper();
TypeReference<HashMap<String, Object>> documentMapType =
new TypeReference<HashMap<String, Object>>() {
};
Map<String, Object> document = mapper.readValue(
new File(file.toString()),
documentMapType);
RenderDocumentDirective renderDocumentDirective = RenderDocumentDirective.builder()
.withToken("helloWorldToken")
.withDocument(document)
.build();
responseBuilder.addDirective(renderDocumentDirective);
speechText.append(" You should now also see my greeting on the screen.");
} catch (IOException e) {
throw new AskSdkException("Unable to read or deserialize the hello world document", e);
}

Spring Boot, Thymeleaf and strings

Hello I'm using spring boot 2.4.x and I want to use thymeleaf as my template engine.
I've added the thymeleaf starter and I've the following test
#Test
void name() {
StringTemplateResolver stringTemplateResolver = new StringTemplateResolver();
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.addTemplateResolver(stringTemplateResolver);
Context ctx = new Context();
ctx.setVariable("franco", "prova");
String processedTemplate = templateEngine.process("<html>${franco}</html>", ctx);
Assertions.assertThat(processedTemplate).isEqualTo("<html>prova</html>");
}
but the templateEngine is not substituting the variable and the value of the processedTemplate variable is the same as the input string.
What's my fault?
Thank you
Thymeleaf won't process variables directly in HTML. You either have to use the text inlining syntax:
<html>[[${franco}]]</html>
or do it the standard way (which is to use attributes prefixed with th:) like this:
<html th:text="${franco}" />
or
<html><span th:text="${franco}" /></html>
(Also, as a side note StringTemplateResolver is the default resolver, so you don't have to configure it. Your complete code can look like this.)
#Test
void name() {
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
Context ctx = new Context();
ctx.setVariable("franco", "prova");
String processedTemplate = templateEngine.process("<html>[[${franco}]]</html>", ctx);
Assertions.assertThat(processedTemplate).isEqualTo("<html>prova</html>");
}

Itext7 PDF Form Not Editable After Writing Data

Following code i am using to write data in pdf form. The output Pdf is not editable.
I need editable pdf after updating data.
public static void main(String[] args) throws IOException {
PdfReader reader = new PdfReader("Input.pdf");
PdfWriter writer = new PdfWriter("Output.pdf");
PdfDocument pdfDocument = new PdfDocument(reader, writer);
//PdfDocument pdfDocument = new PdfDocument(reader, writer,new
StampingProperties().useAppendMode());
PdfAcroForm form = PdfAcroForm.getAcroForm(pdfDocument, false);
form.getField("topmostSubform[0].Page1[0].Id[0]").setValue("12345678");
form.getField("topmostSubform[0].Page1[0].Name[0]").setValue("Name");
form.getField("topmostSubform[0].Page1[0].Sno[0]").setValue("11111111111");
form.getField("topmostSubform[0].Page1[0].Status[0]").setValue("Yes");
form.flush();
pdfDocument.close();
}
If i use StampingProperties().useAppendMode() nothing is writing in out put pdf but is editable.

How to Load templates from external folder using Thymeleaf

I'm working with spring boot and thymeleaf to generate Documents from html templates.
As the templates continuously changes, i want ti to load templates from an external just to add or remove templates from there instead of redeploy the application.
As a POC, when using /resources folder works fine.
This is the error:
Error resolving template "voucher", the template might not exist or might
not be accessible by any of the configured Template Resolvers
This is the context:
applycation.yml
spring:
thymeleaf:
prefix: file:///${PARAMETERS_DIRECTORY_TEMPLATES:/home/app/templates/}
check-template-location: true
suffix=: .html
mode: HTML
encoding: UTF-8
This is my Method:
Where templateName is the template filename and parameters is just a map who has the values to be replaced by the engine.
#Override
public String buildHtmlFromTemplate(String templateName, Map<String, String> parameters) {
TemplateEngine templateEngine = new TemplateEngine();
FileTemplateResolver templateResolver = new FileTemplateResolver ();
templateResolver.setOrder(templateEngine.getTemplateResolvers().size());
templateResolver.setCacheable(false);
templateResolver.setCheckExistence(true);
templateEngine.setTemplateResolver(templateResolver);
return templateEngine.process(templateName, this.resolveHtmlTemplateAttributesContext(parameters));
}
NOTE:
I removed tha applycation yml thymeleaf configs and implemented next code but the error persists.
#Override
public String buildHtmlFromTemplate(String templateName, Map<String, String> parameters) {
TemplateEngine templateEngine = new TemplateEngine();
FileTemplateResolver templateResolver = new FileTemplateResolver ();
templateResolver.setPrefix("/home/skeeter/templates/");
templateResolver.setSuffix(".html");
templateResolver.setTemplateMode("HTML");
templateResolver.setOrder(templateEngine.getTemplateResolvers().size());
templateResolver.setCharacterEncoding("UTF-8");
templateResolver.setCacheable(false);
templateResolver.setCheckExistence(true);
templateEngine.setTemplateResolver(templateResolver);
return templateEngine.process(templateName, this.resolveHtmlTemplateAttributesContext(parameters));
}
0
Curiously, the issue was solved using this code and the /usr/app/templates created with sudo.
I think it was only a permissions issue
.....
#Value("${parameters.directory.templates}")
private String templatesDirectory;
.....
#Override
public String buildHtmlFromTemplate(String templateName, Map<String, String> parameters) {
TemplateEngine templateEngine = new TemplateEngine();
FileTemplateResolver templateResolver = new FileTemplateResolver ();
templateResolver.setPrefix(templatesDirectory);
templateResolver.setSuffix(".html");
templateResolver.setTemplateMode("HTML");
templateResolver.setOrder(templateEngine.getTemplateResolvers().size());
templateResolver.setCharacterEncoding("UTF-8");
templateResolver.setCacheable(false);
templateResolver.setCheckExistence(true);
templateEngine.setTemplateResolver(templateResolver);
return templateEngine.process(templateName, this.resolveHtmlTemplateAttributesContext(parameters));
}
In my case I was using the ClassLoaderTemplateResolver, but after I changed it to FileTemplateResolver I can use the absolute path and it works fine.
Double check that you have read permissions in the directory where you have the templates.

Thymeleaf : template might not exist or might not be accessible by any of the configured Template Resolvers

I have this code:
private static final String EMAIL_INLINEIMAGE_TEMPLATE_NAME = "templateemail.html";
#Bean
public TemplateEngine emailTemplateEngine() {
templateEngine = new SpringTemplateEngine();
templateEngine.addTemplateResolver(this.htmlTemplateResolver());
)
templateEngine.setTemplateEngineMessageSource(this.messageSource);
return templateEngine;
}
private static ITemplateResolver htmlTemplateResolver() {
final ClassLoaderTemplateResolver templateResolver = new ClassLoaderTemplateResolver();
templateResolver.setOrder(Integer.valueOf(0));
templateResolver.setPrefix("classpath:/templates/");
templateResolver.setSuffix(".html");
templateResolver.setTemplateMode(TemplateResolver.DEFAULT_TEMPLATE_MODE);
templateResolver.setCharacterEncoding("UTF-8");
templateResolver.setCacheable(false);
return templateResolver;
}
public void sendEmail(String emailAddress, String title, String body, Locale local, String image) {
if (Boolean.parseBoolean(isEmailServiceActivated)) {
MimeMessage mimeMessage = mailSender.createMimeMessage();
MimeMessageHelper mailMsg = new MimeMessageHelper(mimeMessage);
try {
mailMsg.setFrom(EMAIL_USERNAME);
mailMsg.setTo(emailAddress);
mailMsg.setSubject(title);
// Prepare the evaluation context
ctx.setLocale(local);
ctx.setVariable("imageHeaderResourceName", HEADER_LOGO_IMAGE);
ctx.setVariable("body", body);
ctx.setVariable("imageResourceName", image);
final String htmlContent = this.templateEngine.process(new ClassPathResource(EMAIL_INLINEIMAGE_TEMPLATE_NAME).getPath(), ctx);
mailMsg.setText(htmlContent, true );
mailMsg.addInline(HEADER_LOGO_IMAGE, new ClassPathResource(HEADER_LOGO_IMAGE ) , PNG_MIME);
mailMsg.addInline(image, new ClassPathResource(image) , PNG_MIME);
} catch (MessagingException e) {
e.printStackTrace();
}
mailSender.send(mimeMessage);
}
}
I have templateemail.html file under /templates/ directory. when I launch the sending email method I have this exception :
org.thymeleaf.exceptions.TemplateInputException: Error resolving template "templateemail.html", template might not exist or might not be accessible by any of the configured Template Resolvers
I dont know if it's because the templateEngine can't find my file (I try even with tomcat absolute path and /bin directory but no way ) or I haven't configure the right Template Resolver.
Thank you very much for your help. I
It work now by deleting ".html" in the name of template (the file has the html extension)
private static final String EMAIL_INLINEIMAGE_TEMPLATE_NAME = "templateemail"
Note the non-cross-platform behavior that can occure: on Windows the CamelCase.html template was resolved, but not on Ubuntu linux! There I had to rename it to camelcase.html, all chars in lower case
I had the same issue recently. My problem was that my template had references to other templates that started with /.
For example:
<html ... th:include="/internal/layout-normal :: page"> <-- failed
<html ... th:include="internal/layout-normal :: page"> <-- worked
Both variants worked without problems when I run the application from IntelliJ. However, when packaged and run via java -jar the first line failed.
Removing the / solved the problem for me
Thymeleaf picks up the html files from resources/templates path by using the name of html file.
Hence in this case just removing .html extension from the filename would work!

Resources