XWPF POI paragraph border color red - colors

How to change color of paragraph border.
paragraph border color red
enter image description here

Although apache poi XWPF provides to set paragraph borders using XWPFParagraph.setBorder... methods - for ex. XWPFParagraph.html#setBorderLeft - it not provides setting border colors upto now. So we need using the underlaying low level org.openxmlformats.schemas.wordprocessingml.x2006.main.* classes.
Paragraph borders are set in paragraph properties (pPr). There are paragraph border (pBdr) elements having settings for left, top, right and bottom borders. Those left, top, right and bottom elements then have settings for line type (this is what apache poi provides already), line size and line color. The color is set as RGB-Hex.
Following example provides a method void setBorderLeftColor(XWPFParagraph paragraph, String rgb) to set left border color.
import java.io.FileOutputStream;
import org.apache.poi.xwpf.usermodel.*;
public class CreateWordParagraphBorderColor {
private static void setBorderLeftColor(XWPFParagraph paragraph, String rgb) {
if (paragraph.getCTP().getPPr() == null) return; // no paragraph properties = no borders
if (paragraph.getCTP().getPPr().getPBdr() == null) return; // no paragraph border
if (paragraph.getCTP().getPPr().getPBdr().getLeft() == null) return; // no left border
paragraph.getCTP().getPPr().getPBdr().getLeft().setColor(rgb);
}
public static void main(String[] args) throws Exception {
XWPFDocument document = new XWPFDocument();
XWPFParagraph paragraph = document.createParagraph();
XWPFRun run = paragraph.createRun();
run.setText("Following paragraph with border left and border left color:");
paragraph = document.createParagraph();
paragraph.setBorderLeft(Borders.SINGLE);
setBorderLeftColor(paragraph, "FF0000");
run = paragraph.createRun();
run.setText("Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.");
paragraph = document.createParagraph();
FileOutputStream out = new FileOutputStream("CreateWordParagraphBorderColor.docx");
document.write(out);
out.close();
document.close();
}
}

Related

Apache POI: autoSizeColumn() with text rotation and wrap text

I'm using a prepared .xlsx file and edit it programatically. This is the original:
In my code, I autosize the column:
XSSFSheet sheet = workbook.getSheetAt(0);
sheet.getColumnStyle(COLUMN_H).setWrapText(true);
System.out.println("COL " + sheet.getColumnStyle(COLUMN_H).getWrapText()); // it's 'true'
sheet.autoSizeColumn(COLUMN_H);
The end result looks like this:
I hoped the column would shrink just enough to show all the lines of the text.
I'm using version 5.2.2 of the POI library.
Is this not what autosize does? Is there a way to calculate the prefered width of the column and set it explicitely?
When I double click on the border right of column H, the width is set as expected.
Yes, this is how Sheet.autoSizeColumn works up to now. It cannot do the same as Excel's GUI can do, simply because it does not have the same resources and possibilities. Excel's GUI runs as desktop application and so has access to the full memory and graphical system. Apache POI only has access to the memory which the Java JRE got and the data which is stored in the Excel file. That's not enough to do the same things, the Excel GUI can do.
To be able to auto-size the width of Excel cells the program must know the font metrics and the text content in rich text format for each cell in the column to calculate the needed width for the text. This is what Apache POI tries up to now. And this is expensive enough when you see how much time Sheet.autoSizeColumn consumes only for a little amount of rows. In addition, this needs access to fonts and GUI-classes such as Java AWT for example. This is currently already causing problems in some server-systems.
To be able additional considering the wrap-text case without having explicit line breaks in the text or when text is rotated too, the row heights for each row in the column also needs to be known. Apache POI does not take this into account until now. That's why Sheet.autoSizeColumn can only work correctly when there are explicit line breaks in the text and when the text is not rotated.
The following complete example shows this.
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.ss.util.SheetUtil;
public class ExcelAutoSizeColumn {
public static void main(String args[]) throws Exception {
//String testString = "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.";
String testString =
"Lorem ipsum dolor sit amet,\n"
+"consetetur sadipscing elitr,\n"
+"sed diam nonumy eirmod tempor \n"
+"invidunt ut labore et dolore \n"
+"magna aliquyam erat,\n"
+"sed diam voluptua. At vero eos \n"
+"et accusam et justo duo dolores \n"
+"et ea rebum. Stet clita kasd gubergren,\n"
+"no sea takimata sanctus est Lorem\n"
+"ipsum dolor sit amet.";
String filePath = "./Excel.xlsx";
String fontName = "Calibri";
short fontSize = 11;
//short rotation = 0;
//short rowHeight = -1; //-1 for auto height
short rotation = 90;
short rowHeight = 180*20;
boolean italic = false;
boolean bold = false;
try ( Workbook workbook = new XSSFWorkbook();
java.io.FileOutputStream out = new java.io.FileOutputStream(filePath)) {
Font font = workbook.createFont();
font.setFontHeightInPoints(fontSize);
font.setFontName(fontName);
font.setItalic(italic);
font.setBold(bold);
CellStyle style = workbook.createCellStyle();
style.setFont(font);
style.setWrapText(true);
style.setRotation(rotation);
Sheet sheet = workbook.createSheet();
Row row = sheet.createRow(0);
row.setHeight(rowHeight);
Cell cell = row.createCell(0);
cell.setCellValue(testString);
cell.setCellStyle(style);
double width = SheetUtil.getColumnWidth(sheet, 0, true);
System.out.println(width);
sheet.autoSizeColumn(0, true);
workbook.write(out);
}
}
}
You could file a bug report about this in https://bz.apache.org/bugzilla/buglist.cgi?list_id=201224&product=POI. But I doubt it will be fixed soon, because it will increase the time consuming of that method very much.

How do I align multiple views across multiple axes in SwiftUI?

How do I lay out the following in SwiftUI?
The two circles are centre aligned horizontally along the blue line, and the top circle is vertically aligned with its rectangle along the green line, with the bottom circle vertically aligned with the bottom rectangle along the red line.
There’s no nested HStack/VStack structure that can describe this. We think the solution has something to do with custom alignment guides, but all of the examples we could find stop short of this level of complexity.
It feels like your best bet in this situation would be to use a LazyVGrid. There's a tendency to think of grids being used for collections where we might have long lists of items, but they also work for a known, finite number of children, so I think they'd work here.
In essence, you have two columns of items – both can be flexible to a degree, but it sounds like your column of rectangles needs to expand more. So you could start off by trying something like:
let columns = [
GridItem(.flexible(maximum: 120)),
GridItem(.flexible())
]
var body: some View {
LazyVGrid(columns: columns) {
// row 1, column 1
RoundedRectangle(cornerRadius: 10)
.frame(width: 100, height: 160)
// row 1, column 2
Text("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque tincidunt enim in iaculis tincidunt. Nunc vitae imperdiet dolor")
// row 2, column 1
Circle()
.frame(height: 100)
// row 2, column 2
Text("Integer vitae volutpat urna. Morbi vel pharetra dolor. Interdum et malesuada fames ac ante ipsum primis in faucibus. Mauris ornare a augue id cursus")
}
}
The code above gives you something like:
I've not had the opportunity to use grids in this way myself yet, so haven't played around with all the customisation they offer, but it does feel like this might be the best way to get you what you want without worrying about alignment guides or preferences.

How to adjust widths of the second row in Words table

I have a Word table with custom first row, but the following rows aren't adjusted. Please tell me why, and how to do the same widths of cells of the second row?
XWPFDocument document = new XWPFDocument();
CTDocument1 doc = document.getDocument();
CTBody body = doc.getBody();
if (!body.isSetSectPr()) {
body.addNewSectPr();
}
CTSectPr section = body.getSectPr();
if(!section.isSetPgSz()) {
section.addNewPgSz();
}
CTPageSz pageSize = section.getPgSz();
pageSize.setW(BigInteger.valueOf(15840));
pageSize.setH(BigInteger.valueOf(12240));
XWPFParagraph paragraph = document.createParagraph();
CTSectPr ctSectPr = section ;//paragraph.getCTP().addNewPPr().addNewSectPr();
CTColumns ctColumns = ctSectPr.addNewCols();
ctColumns.setNum(BigInteger.valueOf(1));
paragraph.setAlignment(ParagraphAlignment.CENTER);
XWPFRun test = paragraph.createRun();
test.setFontSize(15);
test.setBold(true);
test.setFontFamily("Times New Roman");
test.setText("Перечни документов, необходимые для применения и исполнения технических регламентов (форма № 21)");
test.addBreak();
XWPFTable supergroupTable = document.createTable();
supergroupTable.setWidth(15200);
//supergroupTable.getCTTbl().addNewTblGrid().addNewGridCol().setW(BigInteger.valueOf(1*720));
//supergroupTable.getCTTbl().getTblGrid().addNewGridCol().setW(BigInteger.valueOf(12*720));
CTTblWidth tblWidth = supergroupTable.getRow(0).getCell(0).getCTTc().addNewTcPr().addNewTcW();
tblWidth.setW(BigInteger.valueOf(400));
supergroupTable.getRow(0).getCell(0).setText("№");
//STTblWidth.DXA is used to specify width in twentieths of a point.
tblWidth.setType(STTblWidth.DXA);
XWPFTableRow supegroupRow = supergroupTable.getRow(0);
XWPFTableCell supergroupCell = supegroupRow.createCell();
tblWidth = supergroupTable.getRow(0).getCell(1).getCTTc().addNewTcPr().addNewTcW();
tblWidth.setW(BigInteger.valueOf(1700));
tblWidth.setType(STTblWidth.DXA);
supergroupCell.setText("Обозначение технического регламента");
supergroupCell = supegroupRow.createCell();
tblWidth = supergroupTable.getRow(0).getCell(2).getCTTc().addNewTcPr().addNewTcW();
tblWidth.setW(BigInteger.valueOf(1700));
tblWidth.setType(STTblWidth.DXA);
supergroupCell.setText("Наименование на русском языке ");
supergroupCell = supegroupRow.createCell();
tblWidth = supergroupTable.getRow(0).getCell(3).getCTTc().addNewTcPr().addNewTcW();
tblWidth.setW(BigInteger.valueOf(880));
tblWidth.setType(STTblWidth.DXA);
supergroupCell.setText("Статус");
supergroupCell = supegroupRow.createCell();
tblWidth = supergroupTable.getRow(0).getCell(4).getCTTc().addNewTcPr().addNewTcW();
tblWidth.setW(BigInteger.valueOf(1700));
tblWidth.setType(STTblWidth.DXA);
supergroupCell.setText("Обозначение документа");
supergroupCell = supegroupRow.createCell();
tblWidth = supergroupTable.getRow(0).getCell(5).getCTTc().addNewTcPr().addNewTcW();
tblWidth.setW(BigInteger.valueOf(1700));
tblWidth.setType(STTblWidth.DXA);
supergroupCell.setText("Наименование на русском языке");
supergroupCell = supegroupRow.createCell();
tblWidth = supergroupTable.getRow(0).getCell(6).getCTTc().addNewTcPr().addNewTcW();
tblWidth.setW(BigInteger.valueOf(880));
tblWidth.setType(STTblWidth.DXA);
supergroupCell.setText("Статус");
supegroupRow = supergroupTable.createRow();
supergroupCell = supegroupRow.getCell(0);
supergroupCell.setText("cell 1");
supergroupCell = supegroupRow.getCell(1);
supergroupCell.setText("cell 2");
supergroupCell = supegroupRow.getCell(2);
supergroupCell.setText("cell 3");
supergroupCell = supegroupRow.getCell(3);
supergroupCell.setText("cell 4");
supergroupCell = supegroupRow.getCell(4);
supergroupCell.setText("cell 5");
supergroupCell = supegroupRow.getCell(5);
supergroupCell.setText("cell 6");
supergroupCell = supegroupRow.getCell(6);
supergroupCell.setText("cell 7");
When I trying to set width of the second row in the same manner that it is set up for the first row the document come to mess and I can't do it the same manner.
Current versions of apache poi provide setWidth methods on high level, so the low level CT... classes are not needed. Using the low level CT... classes one needs special knowledge of the exact XML which needs to be created, else one creates wrong XML very fast. This seems to be the case in your case.
Using current apache poi 5.0.0 creating a table as yours is as simple as this:
import java.io.FileOutputStream;
import org.apache.poi.xwpf.usermodel.*;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSectPr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTPageSz;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STPageOrientation;
import java.math.BigInteger;
public class CreateWordTableCellWidths {
public static void main(String[] args) throws Exception {
XWPFDocument document = new XWPFDocument();
//page settings are not provided high level on apache poi until now.
CTSectPr sectPr = document.getDocument().getBody().addNewSectPr();
CTPageSz pageSz = sectPr.addNewPgSz();
pageSz.setW(BigInteger.valueOf(15840)); //15840 Twips = 15840/20 = 792 pt = 792/72 = 11"
pageSz.setH(BigInteger.valueOf(12240)); //12240 Twips = 12240/20 = 612 pt = 612/72 = 8.5"
pageSz.setOrient(STPageOrientation.LANDSCAPE);
XWPFParagraph paragraph = document.createParagraph();
XWPFRun run = paragraph.createRun();
run.setText("Header line...");
//create table having first row having 7 columns
XWPFTable table = document.createTable(1, 7);
table.setWidth("100%");
//set cell width and content for first row
table.getRow(0).getCell(0).setText("Nr.");
table.getRow(0).getCell(0).setWidth("400");
table.getRow(0).getCell(1).setText("Loremipsumsemitdolor dolorsemitloremipsum semitdolor");
table.getRow(0).getCell(1).setWidth("1700");
table.getRow(0).getCell(2).setText("Lorem ipsum semit dolor dolor semit lorem");
table.getRow(0).getCell(2).setWidth("1700");
table.getRow(0).getCell(3).setText("Lorem ipsum");
table.getRow(0).getCell(3).setWidth("880");
table.getRow(0).getCell(4).setText("Lorem ipsum semit dolor dolor semit lorem");
table.getRow(0).getCell(4).setWidth("1700");
table.getRow(0).getCell(5).setText("Lorem ipsum semit dolor dolor semit lorem");
table.getRow(0).getCell(5).setWidth("1700");
table.getRow(0).getCell(6).setText("Lorem ipsum");
table.getRow(0).getCell(6).setWidth("880");
//create further row
XWPFTableRow row = table.createRow();
row.getCell(0).setText("cell 1");
row.getCell(0).setWidth("400");
row.getCell(1).setText("cell 2");
row.getCell(1).setWidth("1700");
row.getCell(2).setText("cell 3");
row.getCell(2).setWidth("1700");
row.getCell(3).setText("cell 4");
row.getCell(3).setWidth("880");
row.getCell(4).setText("cell 5");
row.getCell(4).setWidth("1700");
row.getCell(5).setText("cell 6");
row.getCell(5).setWidth("1700");
row.getCell(6).setText("cell 7");
row.getCell(6).setWidth("880");
paragraph = document.createParagraph();
FileOutputStream out = new FileOutputStream("CreateWordTableCellWidths.docx");
document.write(out);
out.close();
document.close();
}
}
Only page settings are not provided high level on apache poi until now. So to set page settings using the low level CT... classes is necessary.
For usage in Microsoft Word in general you set cell widths for cells in first row only. Further rows are using those cell widths too except if there are merged cells used.
For usage in Libreoffice or OpenOffice Writer width of all cells in all rows needs to be set.

Dynamically create animation for showing text

I'm currently trying to dynamically create an animation and playing it to show text based on the length of the text and the set speed of characters per second.
What I'm trying to recreate in code is this animation:
So an animation with a property track on the label's property visible_characters with update mode on continuous and interpolation mode on linear
Structure of the scene is:
The script behind the DialogBox node:
extends Control
export(String, MULTILINE) var Text = ""
export(int) var CharactersPerSecond = 100
func _ready():
$Panel/Label.set_text(Text)
print($Panel/Label.get_text())
createAnimation()
$AnimationPlayer.play("show-text")
print("is playing " + str($AnimationPlayer.is_playing()))
print("current animation " + $AnimationPlayer.current_animation)
func createAnimation():
var animationLength = Text.length() / (CharactersPerSecond as float)
print(animationLength)
var animation = $AnimationPlayer.get_animation("show-text")
animation.clear()
var trackIdx = animation.add_track(Animation.TYPE_VALUE)
animation.track_set_path(trackIdx, "Panel/Label:visible_characters")
animation.track_set_interpolation_type(trackIdx,Animation.INTERPOLATION_LINEAR)
animation.value_track_set_update_mode(trackIdx, Animation.UPDATE_CONTINUOUS)
animation.track_insert_key(trackIdx, 0, 0)
animation.track_insert_key(trackIdx, animationLength, Text.length())
For testing purposes the text is being set in the editor using the exported Text variable and is some lorem ipsum.
What happens when I run the scene is that the Panel and Label get shown but no text is shown in the Label, it stays empty, but according the print statements the show-text animation is playing
The printed data in the output window is:
** Debug Process Started **
Godot Engine v3.1.2.stable.mono.official - https://godotengine.org
OpenGL ES 3.0 Renderer: AMD Radeon R7 200 Series
label text: Magnam consequatur vel alias earum accusantium. Nobis voluptatem voluptatem quaerat adipisci voluptas. Numquam id error earum consectetur veniam. Quaerat quibusdam quas sunt alias et blanditiis corporis. Cupiditate rem ut natus est molestiae quidem. Magnam consequatur vel alias earum accusantium. Nobis voluptatem voluptatem quaerat adipisci voluptas. Numquam id error earum consectetur veniam. Quaerat quibusdam quas sunt alias et blanditiis
animationlength: 4.44
is playing: True
current animation: show-text
** Debug Process Stopped **
so the problem was that i still needed to set the length of the animation
just inserting the keys wasn't enough
adding the following line after animation.clear() fixed it:
animation.set_length(animationLength)

iTextSharp: how to scale font to make a multiline it fill a rectangle

Using iTextSharp I have to fill a given rectangle with a text, both in height and width. The text can wrap, I have to find the correct fontsize for it to fill the rectangle.
wrapping the text is not an issue I have a recursive function that return an array of all possible wrapping configuration.
This is not a problem with gdi+, but using iTextSharp I have issues finding the height of my text once it wraps (i.e. contains "\n")
Any help?
I have found this article very usefull, it addess my problem from another point of view:
Centered, multiline text using iTextSharp ColumnText
ADDED: EXAMPLE CODE:
string text = "Lorem Ipsum è un testo segnaposto utilizzato nel settore della tipografia e della stampa. Lorem Ipsum è considerato il testo segnaposto standard sin dal sedicesimo secolo, quando un anonimo tipografo prese una cassetta di caratteri e li assemblò per preparare un testo campione. È sopravvissuto non solo a più di cinque secoli, ma anche al passaggio alla videoimpaginazione, pervenendoci sostanzialmente inalterato. Fu reso popolare, negli anni ’60, con la diffusione dei fogli di caratteri trasferibili “Letraset”, che contenevano passaggi del Lorem Ipsum, e più recentemente da software di impaginazione come Aldus PageMaker, che includeva versioni del Lorem Ipsum.";
Rectangle rect3 = new Rectangle(1000f, 0f, 2000f, 1000f);
// Determine correct font size
Font font3 = new Font(FontFactory.GetFont(FontFactory.HELVETICA, 1000, Font.NORMAL, Color.BLACK));
float fontSize2 = FitText(font3, text, rect3, 1000, PdfWriter.RUN_DIRECTION_DEFAULT);
PdfContentByte contentByte = writer.DirectContent;
Chunk chunk = new Chunk(text, new Font(FontFactory.GetFont(FontFactory.HELVETICA, fontSize2, Font.NORMAL, Color.BLACK)));
Phrase text33 = new Phrase(chunk);
ColumnText columnText4 = new ColumnText(cb);
columnText4.SetSimpleColumn(rect3.GetLeft(0), 0,rect3.GetRight(0), rect3.GetTop(0));
columnText4.SetText(text33);
cb.SaveState();
cb.SetColorStroke(Color.RED);
cb.Rectangle(rect3.GetLeft(0), rect3.GetBottom(0), rect3.GetRight(0), rect3.GetTop(0));
cb.Stroke();
cb.RestoreState();
columnText4.Alignment = Element.ALIGN_LEFT;
columnText4.Go();
doc.Close();
Besides I have throuble even with columnText4.SetSimpleColumn, which render to a different rectangle than my rect3...
EDIT2: using this seem to fix, but I really don't understand why I have to force leadong as fontsize:
columnText4.SetSimpleColumn(rect3.Left, rect3.Bottom, rect3.Right, rect3.Top, fontSize2, Element.ALIGN_LEFT);
Use ColumnText.FitText(Font font, String text, Rectangle rect, float maxFontSize, int runDirection). It returns the font size.
Downloaded the souces, not all is sound, BUT I undestand this:
paragraph use 1.5 * fontsize as leading.
setText ignore leading and use a default value (16f = 12f x 1.5)
so if I want to use setText I have to provvide leading. BUT the function FitText calculate the fontsize with 1 * fontsize leading, so it is not correct to use it with default 1.5 leading and the other function use default 16f...
I managed extending the FitText with an extra parameter: the multiplier (1, 1.5 etc). This saves my day.

Resources