Line Spacing Inside the Table in Word Using Apache POI - ms-word

https://support.content.office.net/en-us/media/fbe67397-658c-4b04-b295-b0d6759e1aaa.jpg
Hello Everyone I need to add Line spacing Before(Spacing about 6pt) effect inside the table.You can see the above image that has a paragraph spacing i need that effect. I am using 5.0.0 version. And checked on many sites. nothing useful. if someone help me that will be great. Thank You in advance :)

To set the paragraph spacing apache poi provides XWPFParagraph.setSpacingBefore and XWPFParagraph.setSpacingAfter. Measurement unit for the int is twentieths of a point. So 8*20 is 8 pt.
In a table one needs get the first paragraph of a XWPFTableCell to set spacing before:
...
XWPFTableRow tableRow = ...
...
XWPFTableCell cell = tableRow.getCell(1);
if (cell.getParagraphs().size() > 0) cell.getParagraphs().get(0).setSpacingBefore(8*20);
...
But if the requirement is vertical aligning in cell, then XWPFTableCell.setVerticalAlignment should be used. But this only can be rendered properly if there is no spacing after the last paragraph which pushs the paragraph upwards.
So
...
XWPFTableRow tableRow = ...
...
XWPFTableCell cell = tableRow.getCell(1);
cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);
if (cell.getParagraphs().size() > 0) cell.getParagraphs().get(cell.getParagraphs().size()-1).setSpacingAfter(0);
...

Related

Unmerge and Assign Values Only Vertically or Horizontally Openpyxl

Using the answer provided by aka863 here: How to split merged Excel cells with Python?
I can unmerge, fill values and copy the styling. My questions is how to make the value assigning/filling process configurable.
I want the user to be able to choose whether the values will be filled vertically/horizontally.
I have tried changing the last loop where we assign the top_left_cell_values to unmerged cells. However I couldn't find a way to make it horizontal/vertical configurable. (I'm planning to use radio buttons and tkinter for this)
Its certainly possible to have the code de-merge cells and fill cells in whichever direction, vertically or horizontally regardless of which way the merge was originally. Or not fill at all, so only the top left cell retains the 'value' of the previously merged cells, which is default on unmerge.
Changing the direction of the fill requires some change and re-calculation on the max row and column values in the iter_rows loop, but is simple enough.
However it seems in your last comment you just want to give the user the option to fill or not fill on horizontal merges. In that case you just need to ask the question, and then run the iter_rows loop only if the response is yes.
The code sample below is based on the answer referenced question.
I'm assuming only single line horizontal merges since you dont mention what if anything should be done with vertical merges in the comment.
The code does initially check and indicate the merge direction either vertically or horizontally so it can be included take some action if a merge is vertical.
On code run after displaying the range and direction of the merge, the question is asked to fill, yes or no. If yes the cells are de-merged and all cells filled with the top left cell value using the iter_rows loop. If answer no then the cells are just de-merged.
from openpyxl import load_workbook
from openpyxl.utils.cell import range_boundaries
wb = load_workbook(filename='foo.xlsx')
st = wb['Sheet1']
mcr_coord_list = [mcr.coord for mcr in st.merged_cells.ranges]
direction_dict = {'v': 'vertical', 'h': 'horizontal'}
for mcr in mcr_coord_list:
print('---------------------------------------------------\n')
merge_direction = ''
min_col, min_row, max_col, max_row = range_boundaries(mcr)
top_left_cell_value = st.cell(row=min_row, column=min_col).value
if min_col == max_col:
merge_direction = 'v'
elif min_row == max_row:
merge_direction = 'h'
print(f"The cell range {mcr} is merged {direction_dict[merge_direction]}ly with the data '{top_left_cell_value}'")
while True:
demerge_fill = input('Do you want the de-merge to fill all cells(y|n)? ')
if demerge_fill.lower() in ["y", "n"]:
break
else:
print('Invalid response')
st.unmerge_cells(mcr)
if demerge_fill == 'y':
for row in st.iter_rows(min_col=min_col, min_row=min_row, max_col=max_col, max_row=max_row):
for cell in row:
cell.value = top_left_cell_value
else:
print(f"Only the top left cell {mcr.split(':')[0]} will contain the data!")
wb.save('merged_tmp.xlsx')

ag-Grid: extend rows till right edge if columns don't occupy full width

In ag-Grid, if the columns occupy a smaller space than the width of the grid, a blank hole appears on the right of the last column. Please see below (example taken from ag-Grid docs):
The UX designers on my team don't like that. They would like to see the rows extended all the way to the right to balance out the look. Is this possible to do with ag-Grid?
Edit: We don't want to use the sizeColumnsToFit option, because on large monitors it produces very wide columns and the grid becomes unreadable. We want to use the autoSize option to compact the columns and fill the hole on the RHS with blank stripes as suggested above.
Yes it is possible. You can call the sizeColumnsToFit function on the ag-Grid api which will fill out the width of the table with the columns.
Take a look at documentation.
Here is a plunker example.
EDIT
Use the property suppressSizeToFit and set it to true to when you call sizeColumnsToFit, it won't have an affect. Apply this property to the defaultColDef and set it to false for the last column. This was, when you call sizeColumnsToFit, only the last column will be set to full width. See the updated plunker above.
this is how i do it:
/**
* if there is "dead space" present on the grid, the columns will be auto sized to fill the gap
* #param gridApi
* #param columnApi
*/
resizeColumnsToFit(gridApi: GridApi, columnApi: ColumnApi, allowShrink = false) {
if (allowShrink) {
gridApi.sizeColumnsToFit();
} else {
const gridBodyWidth = document.getElementsByClassName("ag-root-wrapper")[0].clientWidth; // todo: use grid's id instead of [0] to allow multiple grids on a page
const allColumnsWidth = columnApi.getAllDisplayedColumns().map(c => c.getActualWidth()).reduce((a, b) => a + b, 0);
if (gridBodyWidth > allColumnsWidth) {
gridApi.sizeColumnsToFit();
}
}
}
This method will size columns to fit only when there is "dead" space on the right. Optionaly set allowShrink to true to force resizing even if there is no dead space
I had the same situation and resolved with the following css override:
.ag-center-cols-container {
width: 100% !important;
}
One possible option I've been playing with is adding a fake column at the end to fill the remaining space. To do so, you just need to add a column with options similar to the following to the end of your list of columns:
{
flex: 1,
headerName: '',
}
See this plunker forked from #ViqMontana's example above.
It's not a perfect solution, but wanted to mention it here in case it helps.
This works like Craig Weston's answer but without the need for !important:
.ag-center-cols-container {
min-width: 100%;
}

Content alignment in ITEXT footer/header

hie ..
i have been using itext for the past couple of days and i am facing difficulty in aligning footer content .. if there are two or more lines in footer, is there a way to align each line differently .. i ve tried doing it in the following manner without any success ..
Paragraph footerInfo = new Paragraph("Date :-",FontFactory.getFont("Calibri",9,Font.BOLD));
footerInfo.add("\n");
footerInfo.add(new Paragraph("Place :- "",FontFactory.getFont("Calibri",9,Font.BOLD)));
Paragraph foot1 = new Paragraph("EmpID:-",FontFactory.getFont("Calibri",9,Font.BOLD));
foot1.setAlignment(Element.ALIGN_RIGHT);
footerInfo.add(foot1);
HeaderFooter footer = new HeaderFooter(footerInfo, false);
footer.setBorder(Rectangle.TOP);
document.setFooter(footer);

iText -- How do I get the rendered dimensions of text?

I would like to find out information about the layout of text in a PdfPCell. I'm aware of BaseFont.getWidthPointKerned(), but I'm looking for more detailed information like:
How many lines would a string need if rendered in a cell of a given width (say, 30pt)? What would the height in points of the PdfPCell be?
Give me the prefix or suffix of a string that fits in a cell of a given width and height. That is, if I have to render the text "Today is a good day to die" in a specific font in a PdfPCell of width 12pt and height 20pt, what portion of the string would fit in the available space?
Where does iText break a given string when asked to render it in a cell of a given width?
This is with regard to iText 2.1.6. Thanks.
iText uses the ColumnText class to render content to a cell. This is explained in my book on page 98-99. This means that, just like with ColumnText, you need to make the distinction between text mode and composite mode.
In any case, ColumnText measures the width of the characters and tests if they fit the available width. If not, the text is split. You can change the split behavior in different ways: by introducing hyphenation or by defining a custom split character.
I've written a small proof of concept to show how you could implement custom "truncation" behavior. See the TruncateTextInCell example.
Instead of adding the content to the cell, I have an empty cell for which I define a cell event. I pass the long text "D2 is a cell with more content than we can fit into the cell." to this event.
In the event, I use a fancy algorithm: I want the text to be truncated in the middle and insert "..." at the place where I truncated the text.
BaseFont bf = BaseFont.createFont();
Font font = new Font(bf, 12);
float availableWidth = position.getWidth();
int contentLength = content.length();
int leftChar = 0;
int rightChar = contentLength - 1;
availableWidth -= bf.getWidthPoint("...", 12);
while (leftChar < contentLength && rightChar != leftChar) {
availableWidth -= bf.getWidthPoint(content.charAt(leftChar), 12);
if (availableWidth > 0)
leftChar++;
else
break;
availableWidth -= bf.getWidthPoint(content.charAt(rightChar), 12);
if (availableWidth > 0)
rightChar--;
else
break;
}
String newContent = content.substring(0, leftChar) + "..." + content.substring(rightChar);
PdfContentByte canvas = canvases[PdfPTable.TEXTCANVAS];
ColumnText ct = new ColumnText(canvas);
ct.setSimpleColumn(position);
ct.addElement(new Paragraph(newContent, font));
ct.go();
As you can see, we get the available width from the position parameter and we check how many characters match, alternating between a character at the start and a character at the end of the content.
The result is shown in the resulting PDF: the content is truncated like this: "D2 is a c... the cell."
Your question about "how many lines" can be solved in a similar way. The ColumnText class has a getLinesWritten() method that gives you that information. You can find more info about positioning a ColumnText object in my answer to your other question: Can I tell iText how to clip text to fit in a cell

Line spacing and paragraph alignment in CoreText

I am using CoreText to render multiple columns of text. However, when I set the first letter of the 1st paragraph to a bold, larger font than the rest of the text, I incur 2 issues (both visible in the attached image):
The spacing underneath the first line is too big (I understand that this is because the 1st character could be a g,y,p,q etc.
Lines below the first line now do not line up with corresponding lines in the next column.
Any advice on how to overcome these 2 issues would be greatly appreciated, thank you.
According to the documentation kCTParagraphStyleSpecifierMaximumLineHeight should have solved the problem, but unfortunately does not seem to work at least on IOS 4.3.
CTParagraphStyleSetting theSettings[5] =
{
{ kCTParagraphStyleSpecifierParagraphSpacing, sizeof(CGFloat), &spaceBetweenParaghraphs },
{ kCTParagraphStyleSpecifierParagraphSpacingBefore, sizeof(CGFloat), &topSpacing },
{ kCTParagraphStyleSpecifierLineSpacing, sizeof(CGFloat), &spaceBetweenLines },
{ kCTParagraphStyleSpecifierMinimumLineHeight, sizeof(CGFloat), &lineHeight},
{ kCTParagraphStyleSpecifierMaximumLineHeight, sizeof(CGFloat), &lineHeight}
};
CTParagraphStyleRef paragraphStyle = CTParagraphStyleCreate(theSettings, 5);
To be fair documentation says it's available in OS v10.5 and later.
kCTParagraphStyleSpecifierMaximumLineHeight:
The maximum height that any line in the frame will occupy, regardless of the font size or size of any attached graphic. Glyphs and graphics exceeding this height will overlap neighboring lines. A maximum height of 0 implies no line height limit. This value is always nonnegative.Type: CGFloat.
Default: 0.0.
Application: CTFramesetter.
Available in Mac OS X v10.5 and later.
Declared in CTParagraphStyle.h.
It seems the only way to fix this is with a workaround, which is to create 3 frames for the first column,1 for the W, 1 for the rest of the first sentence and 1 for the rest of the first column.