I'm looking for dificult template use cases!

This petition may sound weird but I really need your help with it!

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.

Let me know your complex GDocs/MSWord templates and I could give you an HTML/CSS version that -hopefully- works better and even one that works in case you weren't able to make it with traditional templates ๐Ÿ˜‰

9 60 3,094
60 REPLIES 60

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 1Image 2Image 3
Caption 1Caption 2Caption 3
Date 1Date 2Date 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.

But I need more challenges to practice!

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:

Have you ever wondered how to add an image to a template but control the size completely and prevent AppSheet from generating an anchor (<a>) aka hyperlink with it?

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="&lt;&lt;[IMG]&gt;&gt;" width="whatever" height="whatever">

If someone wants a template, let me know! 

@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?

Hi @Peter_Bernsen 

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!

@SkrOYC 

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

HTML 

Screenshot 2023-07-21 124526.pngScreenshot 2023-07-21 125626.png

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:

Lubabul_1-1711790671340.png

 

this my HTMl

 <p> <img src="&lt;&lt;[Sender Sign text]&gt;&gt;"
style="width: inherit; height: inherit; object-fit: scale-down; object-position: center center;"/></p>

 format rules :

Lubabul_2-1711791038000.png

can you helping me? 

Another one:

How do you make sure to have the table header on every page after a page break? For example, the data inside the table is so big that it has to break into more pages but the headers are lost?

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!

How can you add page break at will?

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:

Show More
<!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>&lt;&lt;TODAY()&gt;&gt;<br> by &lt;&lt;LOWER(USEREMAIL())&gt;&gt;</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 !

i-admire-that.jpg

Did you know that you could have a dinamic index with hyperlinks to each part of your paginated report using HTML/CSS?

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:Screenshot 2023-05-08 142326.jpg

Seems quite doable, although I would need more info to find the most efficient option

Hello. Can you help with this error?

Error encountered in step with name [New step]: Error: 'Process for Test map' task 'print Maps' Body template. Template could not be loaded due to exception: Name cannot begin with the ' ' character, hexadecimal value 0x20. Line 38, position 22. Error: The document body is empty

<!DOCTYPE html>
<html>

<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <title>OSM</title>

</head>

<style>
  body {}
</style>


<body>
  <p>OSM</p>
  <div id="mapdiv" style="width: 400px; height: 300px;"></div>
  <p id="bbox"></p>
  <p id="lat_lon"></p>
  <p id="max_lat_lon"></p>
  <p id="min_lat_lon"></p>
  <p id="min_lat"></p>
  <p id="max_lat"></p>
  <p id="min_lon"></p>
  <p id="max_lon"></p>

</body>
<script type="text/javascript">

  var markers = [
    [7.35329, 53.45228, 'Start'],
    [7.355662, 53.449621, 'Ende'],
    [7.355662, 53.45228, 'Max'],
    [7.35329, 53.449621, 'Min'],
    [7.354476, 53.450950500000005, "Mitte"]
  ];
  for (var i = 0; i < markers.length; i++) {
    var max_lon = [markers[1][0]]
    var min_lon = [markers[1][0]]
    var max_lat = [markers[1][1]]
    var min_lat = [markers[1][1]]
  }
  for (var i = 0; i < markers.length; i++) {
    var lon = markers[i][0];
    var lat = markers[i][1];


    if (lon > max_lon[0]) {
      max_lon[0] = lon
    }
    if (lon < min_lon[0]) {
      min_lon[0] = lon
    }
    if (lat > max_lat[0]) {
      max_lat[0] = lat
    }
    if (lat < min_lat[0]) {
      min_lat[0] = lat
    }
  }
  var lon_Mitte = (parseFloat(min_lon) + parseFloat(max_lon)) / 2
  var lat_Mitte = (parseFloat(min_lat) + parseFloat(max_lat)) / 2
  var Mitte = lon_Mitte + ", " + lat_Mitte

  // Adapted from: harrywood.co.uk
  epsg4326 = new OpenLayers.Projection("EPSG:4326")

  map = new OpenLayers.Map({
    div: "mapdiv",
    displayProjection: epsg4326   // With this setting, lat and lon are displayed correctly in MousePosition and permanent anchor
  });

  //   map = new OpenLayers.Map("mapdiv");
  map.addLayer(new OpenLayers.Layer.OSM());
  map.addLayer(new OpenLayers.Layer.OSM("Wikimedia",
    {
      attribution: "&copy; <a href='http://www.openstreetmap.org/'>OpenStreetMap</a> and contributors, under an <a href='http://www.openstreetmap.org/copyright' title='ODbL'>open license</a>. <a href='https://www.mediawiki.org/wiki/Maps'>Wikimedia's new style (beta)</a>",
      "tileOptions": { "crossOriginKeyword": null }
    })
  );
  // See https://wiki.openstreetmap.org/wiki/Tile_servers for other OSM-based layers

  map.addControls([
    new OpenLayers.Control.MousePosition(),
    new OpenLayers.Control.ScaleLine(),
    new OpenLayers.Control.LayerSwitcher(),
    new OpenLayers.Control.Permalink({ anchor: true })
  ]);

  projectTo = map.getProjectionObject(); //The map projection (Spherical Mercator)
  var Gps_mitte = new OpenLayers.LonLat(lon_Mitte, lat_Mitte).transform(epsg4326, projectTo);
  var lonLat = new OpenLayers.LonLat(lon_Mitte, lat_Mitte).transform(epsg4326, projectTo);
  var zoom = 15;
  if (!map.getCenter()) {
    map.setCenter((lonLat), zoom);
  }



  // Put your point-definitions here


  var colorList = ["red", "blue", "yellow", "Black"];
  var layerName = [markers[0][2]];
  var styleArray = [new OpenLayers.StyleMap({ pointRadius: 6, fillColor: colorList[0], fillOpacity: 0.5 })];
  var vectorLayer = [new OpenLayers.Layer.Vector(layerName[0], { styleMap: styleArray[0] })];   // First element defines first Layer

  var j = 0;
  for (var i = 1; i < markers.length; i++) {
    if (!layerName.includes(markers[i][2])) {
      j++;
      layerName.push(markers[i][2]);                              // If new layer name found it is created
      styleArray.push(new OpenLayers.StyleMap({ pointRadius: 6, fillColor: colorList[j % colorList.length], fillOpacity: 0.5 }));
      vectorLayer.push(new OpenLayers.Layer.Vector(layerName[j], { styleMap: styleArray[j] }));
    }
  }

  //Loop through the markers array

  for (var i = 0; i < markers.length; i++) {
    var lon = markers[i][0];
    var lat = markers[i][1];
    var feature = new OpenLayers.Feature.Vector(
      new OpenLayers.Geometry.Point(lon, lat).transform(epsg4326, projectTo),
      { description: "marker number " + i }
    );

    vectorLayer[layerName.indexOf(markers[i][2])].addFeatures(feature);
    document.getElementById('lat_lon').innerHTML = 'lonLat: ' + lonLat;
    document.getElementById('max_lat_lon').innerHTML = 'Max_lat_lon: ' + max_lon + ", " + max_lat;
    document.getElementById('min_lat_lon').innerHTML = 'Min_lat_lon: ' + min_lon + ", " + min_lat;
    document.getElementById('max_lat').innerHTML = 'Max_lat: ' + max_lat;
    document.getElementById('min_lat').innerHTML = 'Min_lat: ' + min_lat;
    document.getElementById('max_lon').innerHTML = 'Max_lon: ' + max_lon;
    document.getElementById('min_lon').innerHTML = 'Min_lon: ' + min_lon;

    document.getElementById('bbox').innerHTML = 'Mitte: ' + Gps_mitte;

  }

  for (var i = 0; i < layerName.length; i++) {
    map.addLayer(vectorLayer[i]);
  }

</script>


</html>

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="&lt;&lt;[Logo]&gt;&gt;"
                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="&lt;&lt;[Logo]&gt;&gt;"
                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="&lt;&lt;[Logo]&gt;&gt;"
                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="&lt;&lt;[CodigoQR]&gt;&gt;"
                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="&lt;&lt;[CodigoQR]&gt;&gt;"
                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="&lt;&lt;[CodigoQR]&gt;&gt;"
                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">
        &lt;&lt;Start: Filter(โ€œItemsโ€,[Familia]=[FamiliaInforme])&gt;&gt;
      </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">
        &lt;&lt;Start: Filter(โ€œItemsโ€,[Familia]=[FamiliaInforme])&gt;&gt;
      </p>
      <table>
        <div class="flex-child">
          <div class="inner-flex-container">
            <tr>
              <td>
                <div class="inner-flex-child">
                  &lt;&lt;[IDHerramienta]&gt;&gt;
                </div>
              </td>
              <td>
                <div class="inner-flex-child">
                  &lt;&lt;[Descripcion]&gt;&gt;
                </div>
              </td>
            </tr>
            <tr>
              <td>
                <div class="inner-flex-child">&lt;&lt;[Estado]&gt;&gt;</div>
              </td>
              <td></td>
            </tr>
          </div>
        </div>
      </table>
      <p class="startifend">&lt;&lt;End&gt;&gt;</p>
    </div>
  </body>

This is the result I am looking for, to be able to create a PDF and have it displayed this way

maquetacionmaquetacion

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

I have made progress but I can't get the stickers to appear 3 at a time, they simply appear one below the other, the size is not respected either since they take up from side to side of the page, this is the code:

<!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;
      }
      p {
        font-size: 14pt;
        font-family: "Arial";
        font-style: bold;
      }
      p.matricular {
        font-size: 12pt;
        font-family: "Arial";
        font-style: bold;
        color: red;
      }
      .startend {
        display: none;
      }
      div.flex-container {
        display: flex;
        flex-wrap: wrap;
        justify-content: center;
        gap: 1px;
      }
      div.flex-Logo {
        height: 53px;
        width: 526px;
        text-align: center;
        flex: 1 1 33%;
      }
      div.flex-Herramienra {
        height: auto;
        width: 394px;
        text-align: center;
        font-weight: bold;
        font-family: "Arial";
        font-size: 36pt;
        vertical-align: middle;
      }
      div.flex-QR {
        height: 211px;
        width: 211px;
      }
      p.startifend {
        display: none;
      }

    </style>
  </head>
  <body>
    <div class="flex-container">
      <p class="startifend">
        &lt;&lt;Start: Filter(โ€œItemsโ€,[Familia]=[FamiliaInforme])&gt;&gt;
      </p>
      <div class="flex-Logo">
        <img
          src="&lt;&lt;[Logo]&gt;&gt;"
          style="
            width: inherit;
            height: inherit;
            object-fit: scale-down;
            object-position: center center;
          "
        />
      </div>
      <div class="flex-Herramienra">
        <span style="color: #ea4335">&lt;&lt;[IDHerramienta]&gt;&gt;</span>
        <p>&lt;&lt;[Descripcion]&gt;&gt;</p>
        <p class="matricular">Maquinaria sin matricular</p>
      </div>
      <div class="flex-QR">
        <img
        src="&lt;&lt;[QR]&gt;&gt;"
        style="
          width: inherit;
          height: inherit;
          object-fit: scale-down;
          object-position: center center;
        "
      />
      </div>
      <p class="startifend">&lt;&lt;End&gt;&gt;</p>
    </div>
  </body>
</html>

This is how the PDF is delivered to me:

Captura de pantalla 2023-11-25 165324.png

 

As you can see, more or less the format is what I'm looking for, but it needs to occupy 3 columns and for the QR to be larger, apparently a margin is created around the QR and that makes it smaller than the container

 

I have realized that the pixels that I had configured in the div were too large for the page width that I had assigned, so I am getting closer to achieving what I need, they already appear in 3 columns but the logo is still out of square

Captura de pantalla 2023-11-25 175021.png

Let's see if tomorrow I get another little while and I can solve it.
this is my new code

 

<!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 29.7cm;
        margin: 0pt 0pt 0pt;
        orientation: portrait;
      }
      p {
        font-size: 10pt;
        font-family: "Arial";
        font-style: bold;
      }
      p.matricular {
        font-size: 6pt;
        font-family: "Arial";
        font-style: bold;
        color: red;
      }
      div.flex-container {
        display: flex;
        flex-wrap: wrap;
        justify-content: start;
      }
      div.flex-Logo {
        text-align: center;
        flex: 1 1 33%;
      }
      div.flex-Herramienra {
        height: auto;
        width: 150px;
        text-align: center;
        font-weight: bold;
        font-family: "Arial";
        font-size: 12pt;
        vertical-align: middle;
      }
      div.flex-QR {
        height: 90px;
        width: 90px;
      }
      p.startifend {
        display: none;
      }
    </style>
  </head>
  <body>
    <div class="flex-container">
      <p class="startifend">
        &lt;&lt;Start: Filter(โ€œItemsโ€,[Familia]=[FamiliaInforme])&gt;&gt;
      </p>
      <div class="flex-Logo">
        <img
          src="&lt;&lt;[Logo]&gt;&gt;"
          style="
            width: 180px;
            height: 35px;
            object-fit: scale-down;
            object-position: center center;
          "
        />
      </div>
      <div class="flex-Herramienra">
        <span style="color: #ea4335">&lt;&lt;[IDHerramienta]&gt;&gt;</span>
        <p>&lt;&lt;[Descripcion]&gt;&gt;</p>
        <p class="matricular">Maquinaria sin matricular</p>
      </div>
      <div class="flex-QR">
        <img
          src="&lt;&lt;[QR]&gt;&gt;"
          style="
            width: inherit;
            height: inherit;
            object-fit: scale-down;
            object-position: center center;
          "
        />
      </div>
      <p class="startifend">&lt;&lt;End&gt;&gt;</p>
    </div>
  </body>
</html>
Top Labels in this Space