iText: Different table rows with different cell/column widths - pdf-generation

How to create with Java a table with three rows as follows:
First row has one cell 100% entire table width
Second row has first from the left cell width 50mm, and second 20mm and third 30mm which in total is 100% of table width
Third row has first from the left cell width 30mm, and second 50mm and third 10mm which in total is 90% of table width
How would the code from the iText look like?

So you want to use iText to create a table that looks like this:
The PDF in the screen shot was created using the TableMeasurements example. The resulting PDF can also be downloaded for inspection: table_measurements.pdf
The first thing that jumps to the eye when looking at this screen shot is the fact that the table doesn't look "complete". This means that we will have to complete the table the way I already explained on SO yesterday (and many times before that): Why the 2nd row of table won't be written? (which was actually a duplicate of How to generate pdf if our column less than the declared table column and ItextSharp, number of Cells not dividable by the length of the row and Odd Numbered Cell Not Added To Pdf and PdfTable: last cell is not visible and ...)
In the comment section, I was asked:
How can I complete row with cells with no border?
I answered:
Use table.getDefaultCell().setBorder(Rectangle.NO_BORDER);
Note that PdfPCell.NO_BORDER also works as PdfPCell extends the Rectangle class.
In your case, we'd have something like this:
public void createPdf(String dest) throws IOException, DocumentException {
Document document = new Document();
PdfWriter.getInstance(document, new FileOutputStream(dest));
document.open();
PdfPTable table = new PdfPTable(10);
table.setTotalWidth(Utilities.millimetersToPoints(100));
table.setLockedWidth(true);
table.getDefaultCell().setBorder(PdfPCell.NO_BORDER);
table.addCell(getCell(10));
table.addCell(getCell(5));
table.addCell(getCell(3));
table.addCell(getCell(2));
table.addCell(getCell(3));
table.addCell(getCell(5));
table.addCell(getCell(1));
table.completeRow();
document.add(table);
document.close();
}
To make the example more realistic, I created a table with an exact width of 100 mm. For the width to be acknowledged, I lock the width. As already explained, I make sure that default cells have no border. After adding all the cells with the different widths (10 cm, 5 cm, 3 cm, 2 cm, 3 cm, 5 cm, 1 cm), I complete the row.
What does the getCell() method look like, you might wonder. This was already answered by Amedee in the comments (which for some reason you ignored):
private PdfPCell getCell(int cm) {
PdfPCell cell = new PdfPCell();
cell.setColspan(cm);
cell.setUseAscender(true);
cell.setUseDescender(true);
Paragraph p = new Paragraph(
String.format("%smm", 10 * cm),
new Font(Font.FontFamily.HELVETICA, 8));
p.setAlignment(Element.ALIGN_CENTER);
cell.addElement(p);
return cell;
}
We create a PdfPCell and we set the colspan to reflect the width in cm. I added some more fancy stuff. I didn't use any functionality in this example that isn't explained on the official web site or on StackOverflow.
For more rowspan and colspan examples, please take a look at the Colspan and rowspan section in the official documentation.

Related

Fitting Vaadin grid into the screen

I am displaying books information in the Vaadin grid. It is displayed almost as I wanted it, but still having problem that I don't know how to solve. Therefore I would appreciate advice(s). Here is how I am creating this grid:
private void createBooksTable() {
this.booksTable = new Grid<>();
this.booksTable.setWidth("100%");
this.yearRenderer = new ActionYearRenderer();
this.booksTable.addColumn(this.yearRenderer).setWidth("8%");
this.booksTable.addColumn(new NewTagRenderer()).setWidth("3%");
this.booksTable.addColumn(new AuthorListRenderer()).setWidth("18%");
this.booksTable.addColumn(new TitleRenderer()).setWidth("50%");
this.booksTable.addColumn(new RatingRenderer()).setWidth("4%");
this.booksTable.addColumn(new ReaderRatingRenderer()).setWidth("3%");
this.booksTable.addColumn(new StatusRenderer()).setWidth("5%");
this.booksTable.setItemDetailsRenderer(new BookDetailsRenderer());
}
As you can see, the sum of all width is less than 100%, but last column is going outside of the screen and being cut. Maybe it happening because of some default column padding, as I see quite a gap between columns. I didn't find a way to fit all columns into the screen. If you know the way to do it, please tell me.
I would recommend set the widest column to grow the remaining space instead of setting definitive percent width.
this.booksTable.addColumn(new TitleRenderer()).setFlexGrow(1);

Is there a way to select a random cell from an HTML table and change its background color?

I need to randomly select a single cell from a 5X5 table and change its background color. I would like to do this by choosing a random index location in the table.
I want to do this:
table > tr:nth-child(Random Number between 1 and 5) > td:nth-child(Random number between 1 and 5){
background-color: aqua;
}
I figured it out. Used this:
let selected = document.getElementById("table").rows[Math.floor(Math.random() * 5)].cells[Math.floor(Math.random() * 5)];
selected.id = "selected";
Ideally I would generate the random numbers, one for the and one for the in javascript and then pass the value to the css style sheet.
assign an id to the tds and make an array that contain the ids of these cells choose randomly from the array and change the style color of the cell matching the id
you might need to use javascript
PS if my answer helped you please upvote or choose it as answer if it was what you're looking for

Fit columns to content in handsontable

I am new to handsontable, and I can not achieve a goal as simple as to have the columns width as long as the content of the cells. Even if I have space enough in handsontable parent to display the full content of the table, some columns overlap the content of some cells.
I do not want to stretch the table to its parent. Just to show the full table contents (as I have space enough).
Update
The answer of fap is right.
I have realized the problem does not come from the basic definition of the table but for the definition of a renderer do on cells.
cells: function (row, col, prop) {
var cellProperties = {};
if (row === 0) {
cellProperties.renderer = firstRowRenderer;
}
return cellProperties;
}
function firstRowRenderer(instance, td, row, col, prop, value, cellProperties) {
Handsontable.renderers.TextRenderer.apply(this, arguments);
td.style.fontWeight = 'bold';
td.style.color = 'green';
td.style.background = '#CEC';
}
It is after the renderer is applied when the content does not fit into handsontable cells and it does not resize. This is the real problem I am facing.
Just don't specify any width for the table and/or columns. Handsontable will size the columns depending of the longest value there is in their respective cells.
See this simple example.
Note that if you edit the values, the column resize dynamically.
But what if you have a value that expand the column width so much that your table is wider than your screen ? Well, if you don't really want that (and I assume that you don't otherwise what's the point of delimiting your columns and/or your table in the first place ?), you can use the option preventOverflow :
preventOverflow: 'horizontal',
As you can see in this example, it will automatically create a navigate bar that prevent your table to go off screen but still size the columns in order to see all your data.

birt report generic style for all rows in table

I am trying to create a generic style for all rows in my data table. I have been looking around and there seems to be a function I can use named rownum.
I tired to create the style like this...
row["__rownum"] Less than 0
then colour = Red
But this is not right. Can someone tell me the right way to do this so I can apply the style to multiple cells in my table.
Also where can i find documentation on what sort of functions like this are available?
thanks
I know two ways how you can specify conditional styles in BIRT:
You can write an "onRender" eventHandler (either in Java or JavaScript) for your row. In JavaScript it could looks as follow:
if (row["__rownum"] % 2 == 0) {
this.getStyle().backgroundColor = "red";
} else {
this.getStyle().color = "red";
}
Or create a new BIRT style with a highlight-rule like follows:
row["__rownum"] % 2 equals to 0 then
Set Color or whatever or apply another style
Instead of creating a new style, that you will have to assign to target elements, you can also modify one of the predefined styles, if you find a one matching your targets.
Both EventHandler and Styles can be assigned to various element: Cells, Rows, Tables, Report...
Links you may find helpful:
https://www.eclipse.org/birt/phoenix/deploy/reportScripting.php
http://help.eclipse.org/helios/index.jsp?topic=%2Forg.eclipse.birt.doc.isv%2Fmodel%2Fapi%2Forg%2Feclipse%2Fbirt%2Freport%2Fmodel%2Fapi%2FElementFactory.html
BIRT: Alternating row Color in a table group

Algorithm to layout a table of contents on a fixed-sized page (multi-column)

I'm writing a table of contents to a standard 8.5in x 11in page. Orientation (landscape versus portrait) is a variable. I can write my TOC to an inner region when x-inch margins are applied to the page (where x is variable).
The raw data is a table with two columns: Topic and Page (i.e. { "Animals" , 1 } , { "Big Plants" , 2 } , { "Small Plants" , 2 } ). This is not a nested TOC - there are no "subtopics". All topics are at the same level of importance and font size is fixed for all text.
I want to allow for 1 or more columns of TOC per page and I'm allowing multiple pages of TOC if needed. The layout is completely dependent on text in the Topic column. If the topics are short, you can imagine putting 2 columns in portrait orientation, or 3 columns in landscape orentation. If there are long topic names, then maybe only 1 column will fit (if very long, then its ok to use multiple lines for a topic). If there are many topics, then I might spill over to multiple pages. The goal is to put as much TOC info as possible on each page.
I realize this is a hard problem. There's a number of details that I haven't explored (i.e. do all pages have to have the same number of columns?). I'm just looking for a start...something simple enough to implement in an hour or two that does the job. Anything semi-intelligent is better than forcing a 1-column TOC with character counts to determine how many rows to place on a page.
First you need a few variables:
Line_hight (inches per TOC line)
Max_TOC_width (inches of the longest TOC name)
Max_pagenum_width (inches width of the largest page number when printed)
Left, Right, Top, Bottom _border (inches of the border around the page)
Then it's pretty easy to calculated.
Lines_Per_Page = Floor( (Page_Height - Top_Border - Bottom_Border) / Line_Height )
Columns_Per_Page = Floor( (Page_Width - Left_Border - Right_Border) / (Max_TOC_Width + Max_PageNum_Width) )
Total_TOC_Per_Page = Lines_Per_Page * Columns_Per_Page
FYI: Floor( ) means round down to the nearest integer. Floor(5.9) = 5, Floor(0.1) = 0
Assuming you want all columns to be the same width:
Do one pass through the table finding the (printed) width of the longest TOC entry.
Divide the page width minus margins and take the floor to figure out how many columns you can fit.
Divide the page height minus margins by the height of a line and take the floor to figure out how many lines per column.
Repeat steps 2 and 3 in the other page orientation (e.g., landscape).
Choose the one that gives the most slots (rows times columns).
The math is slightly more complicated, since you need to account for a "gutter" between the columns. This is easily accomplished by padding your widest value.

Resources