I made a post days ago about the fact that we can create really, really, good reports using HTML/CSS.
Part 1 - Almost pixel perfect pdf reports from aut... - Google Cloud Community
I have practicing a lot and I keep being impressed by the amount of things that can be done compared to the traditional and kind of basic GDocs/MSWord way.
But I don't have all the use cases that could benefit from this amazing and powerfull way of templates.
That's why I'm asking you to give some of the most headache-given templates and maybe even ones that you weren't able to make to see how this thing I've learning could help you and also others!
At the same time I'd love to use some of these on my Part 2 of Pixel Perfect reports.
I'm planning to show you the use of the default AppSheet html-to-pdf conversion tool and a third party one that has full support for CSS Paged Media Module (the one that provides header, footer, automatic numbering, and more!)
As I said on the Part 1 of the trick, I'm really excited about all of this because of how powerful it is.
This does look really promising, I'll have to dust off my CSS skills, I used to do a lot of web page development!
There was a question on here recently, about a week ago I think, but I couldn't find it. From what I remember there person wanted to display three records side by side in a template. The records had an image, comment and date I think and they wanted it to appear like this:
Image 1 | Image 2 | Image 3 |
Caption 1 | Caption 2 | Caption 3 |
Date 1 | Date 2 | Date 3 |
The problem is of course with a template, when you iterate through records and use tables, you can only get a row at a time. I'm pretty sure that if each table was a record (so the start and end expressions wrap a <table> rather than a <tr>) then you could use CSS to place the tables alongside each other How To Create Side-by-side Tables
Are you talking about this one?
Re: Email template - Google Cloud Community
I gave him an answer where I made a template with a div container with display: flex
That's the one! Obviously too easy then, I'll have to think of something more difficult ๐
Nah, I would have ended given up two months ago with something like that.
Now I'm already able to create a full book with the Paged Media Module.
It's the one doing the magic
I'm going to share some reference to good articles and videos about it on the Part 2 of the trick.
You may well be doing this already, but perhaps some of the CSS itself could be stored in tables in AppSheet. This could allow for users to select the "theme" or other options for their reports. You could have some specific styling options like font and background colours stored either in user settings or a user preferences table. Then pull them into the template along with the data, either selecting from a predefined list of classes or IDs or even actual values in the style section of the header.
About that, I haven't played with AppSheet expression inside the CSS, just on HTML.
I tried a very simple thing some time ago when I was just starting on this and it didn't work.
BTW, @Phil I always wondered about <<expressions>> on CSS. Do you have any insight that can be helpfull?
If anyone is interest:
You need a format rule on the IMG column to make it Text and then on your HTML template you call the IMG collumn inside the <img> tag as source.
Like this:
<img src="<<[IMG]>>" width="whatever" height="whatever">
@SkrOYC I would like to have some templates, also how a temaplate looks like with a header and that the next page the childtable-output starts on a proper place beneath a header?
When it comes to headers and footers, the AppSheet backend doesn't support it (they use Skia, same one used by Chromium), but I'm ending my Part 2 where I explain some workarounds using another service that supports full CSS styling.
About the table headers, yes, HTML tables support that by default. So if you have a lot of rows, the next page will have the table header.
Do you have a screenshot of your actual template?
Is not working!
You made the format rule?
Dear friend good morning
I really need a photo ID card from Appsheet!
I have columns in Google Sheets that contain URLS for external images; And data such as Name, date of birth, document number, etc.
Can you provide me with the code of such a template to be sent by email in Task?
Helpme
Hi @SkrOYC ,
I tried to remove the signature image link within the images and followed your html code, but the image does not appear in the generated PDF file, like this:
|
this my HTMl
<p> <img src="<<[Sender Sign text]>>"
style="width: inherit; height: inherit; object-fit: scale-down; object-position: center center;"/></p>
format rules :
can you helping me?
Where do I input this?
I have an app for job scheduling, and I'd like the drivers to be able to upload a high resolution picture of their jobsite when it is finished.
The solution I mentioned considers HTML templates
Another one:
Well, it's a GDocs/MSWord template problem.
Table headers on HTML make this work by default.
If the data is too long and there are page breaks, the info on the <thead> is printed again on the next page.
Now you know!
CSS makes it easy.
There is a property that can be added to any html tag.
You can make it add a page break before or after a certain tag, for example before tables, titles, paragraphs, images, etc.
This way you could make a paginated report where each Title is on a new page and at the top of it
An example of this is on my Part 1 post explaining the usage of HTML/CSS as templates:
Part 1 - Almost pixel perfect pdf reports from aut... - Google Cloud Community
Just make a text file with this inside:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<style>
@Page {
size: 8.5in 11in;
margin: 0pt 0pt 0pt;
}
div.centered {
width: 100%;
align-items: center;
text-align: center;
}
div.alone {
page-break-before: always;
}
table.First-one {
width: 100%;
align-items: center;
border-collapse: collapse;
border-left: red solid 3pt;
border-right: red solid 3pt;
}
tr.header {
border-top: red solid 3pt;
border-bottom: black solid 3pt;
}
th {
padding: 6pt;
}
tr.body:last-child {
font-size: 12pt;
font-weight: bold;
border-bottom: red solid 3pt;
border-top: red solid 2pt;
}
td.number {
text-align: right;
padding-right: 4pt;
}
</style>
</head>
<body>
<div class="centered">
<h1>This is a sample doc made today<br><<TODAY()>><br> by <<LOWER(USEREMAIL())>></h1>
</div>
<div>
<table class="First-one">
<colgroup>
<col style="width: 15%;"/>
<col style="width: 30%;"/>
<col style="width: 40%;"/>
<col style="width: 15%;"/>
</colgroup>
<thead>
<tr class="header">
<th>HEADER<br>This one is 15% of the width</th>
<th>HEADER<br>This one is 30% of the width</th>
<th>HEADER<br>This one is 40% of the width</th>
<th>HEADER<br>This one is 15% of the width</th>
</tr>
</thead>
<tbody>
<tr class="body">
<td>ROW 1</td>
<td>ROW 1</td>
<td>ROW 1</td>
<td class="number">15</td>
</tr>
<tr class="body">
<td>ROW 2</td>
<td>ROW 2</td>
<td>ROW 2</td>
<td class="number">5</td>
</tr>
<tr class="body">
<td>ROW 3</td>
<td>ROW 3</td>
<td>ROW 3</td>
<td class="number">24</td>
</tr>
<tr class="body">
<td colspan="3" style="text-align: center;">Total</td>
<td class="number">44</td>
</tr>
</tbody>
</table>
</div>
<div class="centered alone">
<h1>And this is on a new page. Page break baby!</h1>
</div>
<div>
<table class="First-one">
<colgroup>
<col style="width: 15%;"/>
<col style="width: 30%;"/>
<col style="width: 40%;"/>
<col style="width: 15%;"/>
</colgroup>
<thead>
<tr class="header">
<th>HEADER<br>This one is 15% of the width</th>
<th>HEADER<br>This one is 30% of the width</th>
<th>HEADER<br>This one is 40% of the width</th>
<th>HEADER<br>This one is 15% of the width</th>
</tr>
</thead>
<tbody>
<tr class="body">
<td>ROW 1</td>
<td>ROW 1</td>
<td>ROW 1</td>
<td class="number">15</td>
</tr>
<tr class="body">
<td>ROW 2</td>
<td>ROW 2</td>
<td>ROW 2</td>
<td class="number">5</td>
</tr>
<tr class="body">
<td>ROW 3</td>
<td>ROW 3</td>
<td>ROW 3</td>
<td class="number">24</td>
</tr>
<tr class="body">
<td colspan="3" style="text-align: center;">Total</td>
<td class="number">44</td>
</tr>
</tbody>
</table>
</div>
</body>
</html>
And save it as .html
Then use it instead of a GDocs/MSWord file and you will see
Thank you @SkrOYC !
Well, with some Start: expressions, this is a piece of cake.
Coming soon on my Part 2
Part 1 - Almost pixel perfect pdf reports from aut... - Google Cloud Community
@Aurelien @Peter_Bernsen @graham_howe
Take a look at Part 2, for sure you will find something useful there
Part 2: Pixel perfect paginated reports - Google Cloud Community
@graham_howe wrote:You could have some specific styling options like font and background colours stored either in user settings or a user preferences table
Hey budy! I was taking a look at these comments and found that I already did this on Part 3, I'm planning on posting it on the next 2 weeks. So I guess you will like it @graham_howe
I didn't added CSS inside a record but used some styling that's applied dynamically via CSS
Hi @SkrOYC,
Firstly, I have to say that you are doing a great job sharing all that stuff with us. Thank you for that! I think I have a question directly related to this topic but wasn't sure if this is the best place to ask this question. The thing is about custom HTML templates, Outlook & AppSheet... Do you also find it troublesome? Maybe you have some tricks that are important to know while coding and implementing. I write quite a lot of templates and there is always a problem with rendering in Outlook desktop app. This topic is about difficult template use cases, here it is (at least for me)๐
Regards
When it comes to Email, please check this awesome site:
Welcome to the arrogantly named library of, Good Email Code | good-email-code
The thing is, each email client can render the email differently. Outlook is the worst of them (and I find Thunderbird to be the best, the one I use btw) because it renders HTML using MSOffice or particularily MSWord's engine.
So, long story short, you can only do some stuff look great with Outlook and HTML emails
Thanks for this great resource!
Please forgive me if this reply seems a bit dense, but I am just hoping to clarify as to not make too big of a fool of myself on a public forum.
I have spent the past few months pouring over your incredibly informative posts from March, April, and October of 2022, regarding HTML/CSS templates for AppSheet, as well as several other resources and references, including many that you have listed/suggested in your posts. While I will be the first to admit that I am newer to HTML and CSS, I have struggled through now countless attempts, even using many of your great examples, to formulate a template that works for my needs. In truth, I am not even sure if what I am attempting to do is even considered all that โcomplexโ or if I am just still that novice to not know any better. So now, feeling a little embarrassed and quite bested by this entire process, I have to askโฆIf I am reading your original post correctly, you stating that you are willingly creating, as personal practice, HTML/CSS templates for those with complex template issues based on their need? And, If I am correct in that interpretation of your original post from March of 2022, then, is this offer still on the table, cause it might just save my life or at least my sanity!
Hi @JessicaIrish and thanks for stoping by this post.
I'm willing to help on a best-effort basis and publicly in this forum to help you with the template as well as others understanding it. This means that I would make the template you need and upload it to my GitLab so that you/anyone can grab it from there and learn.
Based on that I suggest you to give me the most complicated part so that you can then develop the rest. In other words, I'd just make sure that it makes sense in HTML/CSS and all AppSheet expressions are on your own. This doesn't mean that you cannot open another thread and ask for help with them of course, and I'd be happy to keep giving support there
Awesome! Thank you! Let me write up what I am trying to accomplish and collect some versions of my many attempts so that I can clearly convey where I am struggling and I will post back with more detail.
What level of complexity could you do with regards to images and charts?
Could you do something like this:
Seems quite doable, although I would need more info to find the most efficient option
Be aware that using Javascript is something very limited considering that those actions have to run on server and we don't know for sure the limits of Skia
Very good, your publications have helped me a lot in creating and controlling the behavior of my PDFs created in Appsheet.
But I am encountering a difficulty which I don't know where to deal with since my knowledge is very limited.
I am trying to create a PDF which is a layout to send to the printer of a filtered column, the difficulty I am encountering is being able to layout with a table in which there are different widths, heights and combinations of cells that each individual sticker forms and take advantage of the maximum role in printing, for this I need to create correlative stickers of 3 by 3, I found your response to a publication where you did it using div.flex-container and div.flex-child, the truth is that I have tried it and it works for me but I don't know how to give it specific widths ad heights for a layout
This is the html of how the layout should look
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<style type="text/css">
@Page {
size: 21cm 29cm;
margin: 0pt 0pt 0pt;
orientation: portrait;
}
table {
width: 21cm;
}
.mediatabla {
width: 100%;
}
td {
padding: 0pt;
}
p {
font-weight: normal;
text-decoration: none;
font-size: 8pt;
font-family: "Arial";
font-style: normal;
}
div {
object-position: center center;
}
.startend {
display: none;
}
.s3 {
background-color: #ffffff;
text-align: center;
font-weight: bold;
color: #000000;
font-family: "Arial";
font-size: 14pt;
vertical-align: middle;
white-space: nowrap;
direction: ltr;
padding: 2px 3px 2px 3px;
}
.s1 {
background-color: #ffffff;
text-align: center;
font-weight: bold;
color: #ea4335;
font-family: "Arial";
font-size: 36pt;
vertical-align: middle;
white-space: nowrap;
direction: ltr;
padding: 2px 3px 2px 3px;
line-height: 86px;
}
.s4 {
background-color: #ffffff;
text-align: center;
font-weight: bold;
color: #ea4335;
font-family: "Arial";
font-size: 12pt;
vertical-align: middle;
white-space: nowrap;
direction: ltr;
padding: 2px 3px 2px 3px;
}
</style>
</head>
<body>
<table>
<tbody>
<tr style="height: 53px">
<td class="s0" colspan="2">
<div style="width: 526px; height: 53px">
<img
src="<<[Logo]>>"
style="
width: inherit;
height: inherit;
object-fit: scale-down;
object-position: center center;
"
/>
</div>
</td>
<td class="s0" colspan="2">
<div style="width: 526px; height: 53px">
<img
src="<<[Logo]>>"
style="
width: inherit;
height: inherit;
object-fit: scale-down;
object-position: center center;
"
/>
</div>
</td>
<td class="s0" colspan="2">
<div style="width: 526px; height: 53px">
<img
src="<<[Logo]>>"
style="
width: inherit;
height: inherit;
object-fit: scale-down;
object-position: center center;
"
/>
</div>
</td>
</tr>
<tr style="height: 86px">
<td class="s1">AND-1</td>
<td class="s2" rowspan="4">
<div style="width: 211px; height: 206px">
<img
src="<<[CodigoQR]>>"
style="
width: inherit;
height: inherit;
object-fit: scale-down;
object-position: left bottom;
"
/>
</div>
</td>
<td class="s1">AND-2</td>
<td class="s2" rowspan="4">
<div style="width: 211px; height: 206px">
<img
src="<<[CodigoQR]>>"
style="
width: inherit;
height: inherit;
object-fit: scale-down;
object-position: left bottom;
"
/>
</div>
</td>
<td class="s1">AND-3</td>
<td class="s2" rowspan="4">
<div style="width: 211px; height: 206px">
<img
src="<<[CodigoQR]>>"
style="
width: inherit;
height: inherit;
object-fit: scale-down;
object-position: left bottom;
"
/>
</div>
</td>
</tr>
<tr style="height: 58px">
<td class="s3">Andamio DACAME multi. 2 cuerpos</td>
<td class="s3">Andamio Aluminio PaxTower 1T</td>
<td class="s3">Andamio Aluminio PaxTower 1T</td>
</tr>
<tr style="height: 41px">
<td class="s4">Maquinaria sin matricular</td>
<td class="s4">Maquinaria sin matricular</td>
<td class="s4">Maquinaria sin matricular</td>
</tr>
<tr style="height: 18px">
<td class="s5"></td>
<td class="s5"></td>
<td class="s5"></td>
</tr>
<tr style="height: 53px">
<th style="height: 53px" class="row-headers-background"></th>
</tr>
</tbody>
</table>
</body>
</html>
This code is how it should look, but what I need is that through the Start End, a filtered list looks like that, that is, 3 labels at a time
I am using this expression that returns the data I want, but I need to include it in the table
<p class="startifend">
<<Start: Filter(โItemsโ,[Familia]=[FamiliaInforme])>>
</p>
and I have tried adding your sample like this but it doesn't work
<style>
@Page {
size: 21cm 29cm;
margin: 0pt 0pt 0pt;
orientation: portrait;
}
div.flex-container {
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: 1px;
}
div.flex-child {
height: auto;
width: 30vw;
text-align: center;
}
p.startifend {
display: none;
}
td{
width: 6.5cm;
height: 1cm;
}
</style>
</head>
<body>
<div class="flex-container">
<p class="startifend">
<<Start: Filter(โItemsโ,[Familia]=[FamiliaInforme])>>
</p>
<table>
<div class="flex-child">
<div class="inner-flex-container">
<tr>
<td>
<div class="inner-flex-child">
<<[IDHerramienta]>>
</div>
</td>
<td>
<div class="inner-flex-child">
<<[Descripcion]>>
</div>
</td>
</tr>
<tr>
<td>
<div class="inner-flex-child"><<[Estado]>></div>
</td>
<td></td>
</tr>
</div>
</div>
</table>
<p class="startifend"><<End>></p>
</div>
</body>
This is the result I am looking for, to be able to create a PDF and have it displayed this way
maquetacion
Try this:
/* Parent */
display:flex
/* Children */
flex: 1 1 33%;
Forgive my ignorance, that's in the CSS, but how do I insert it in the HTML to respect the structure of the table with different widths, heights and cell combinations?
HTML would be somthing like:
<div> <!-- Parent -->
<div> <!-- Children -->
<div/>
<div> <!-- Children -->
<div/>
<div> <!-- Children -->
<div/>
<div> <!-- Children -->
<div/>
<div/>
HTML doesn't need to change, just the CSS
The html that I have given you of the table would be fine then? I just modify the CSS, try it and tell you.
Sorry, I didn't see the code in much detail as I'm not having too much time.
You need to not use a table for it, just simple divs like my example above
User | Count |
---|---|
18 | |
15 | |
10 | |
7 | |
4 |