How can I reduce the line spacing between "Section 1" and "Alert" using IText 7?
These are values stored in the table of database
<h3 style=color:#0000ff;><strong>Section 1</strong></h3>
<h4><strong>- Alert</strong></h4>
I have tried without success these links because don't changing the line spacing between "Section 1" and "Alert"
https://kb.itextpdf.com/home/it7kb/faq/how-to-change-the-line-spacing-of-text
How to adjust spacing between paragraphs in iText7
My code below
if (dt.Rows.Count > 0)
{
for (int i = 0; i < dt.Rows.Count; i++)
{
contents = new Paragraph(dt.Rows[i]["contents"].ToString())
.SetTextAlignment(TextAlignment.JUSTIFIED)
.SetFontSize(12)
.SetMultipliedLeading(0.0f);
List<IElement> lst = HtmlConverter.ConvertToElements(dt.Rows[i]["contents"].ToString()).ToList();
for (int j = 0; j < lst.Count; j++)
{
IBlockElement element = (IBlockElement)lst[j];
if (dt.Rows[i]["contents"].ToString().StartsWith("<h3 style=color:#0000ff;><strong>Section"))
{
contents.SetFontSize(12)
.SetBold()
.SetFontColor(ColorConstants.BLUE)
.SetMultipliedLeading(0.0f);
}
else if (dt.Rows[i]["contents"].ToString().StartsWith("<h4><strong>- "))
{
contents.SetFontSize(10)
.SetBold()
.SetFontColor(ColorConstants.BLACK)
.SetMultipliedLeading(0.0f);
}
else
{
contents.SetFontSize(10)
.SetFontColor(ColorConstants.BLACK)
.SetMultipliedLeading(0.0f);
}
document.Add(element);
}
}
dest = filename.ToString();
}
You're creating a Paragraph objects (called contents) from the HTML strings and applying properties to it, but not adding those objects to the document. You're also creating a List of elements by having HtmlConverter process the HTML strings. Those elements are added to the documents.
So it's expected that none of the properties that are set on contents are visible in the PDF document.
You can simply rely on HtmlConverter to process the CSS properties.
String[] htmls = {
"<h3 style=\"color:#0000ff;\"><strong>Section 1</strong></h3>",
"<h4><strong>- Alert</strong></h4>"
};
PdfWriter writer = new PdfWriter("SO66694693.pdf");
PdfDocument pdfDoc = new PdfDocument(writer);
Document document = new Document(pdfDoc);
for (int i = 0; i < htmls.Length; i++)
{
IList<IElement> lst = HtmlConverter.ConvertToElements(htmls[i]);
for (int j = 0; j < lst.Count; j++)
{
IBlockElement element = (IBlockElement)lst[j];
document.Add(element);
}
}
document.Close();
Output:
When adjusting the bottom margin on the first element and the top margin on the second element:
"<h3 style=\"color:#0000ff;margin-bottom: 0px;\"><strong>Section 1</strong></h3>",
"<h4 style=\"margin-top: 0px;\"><strong>- Alert</strong></h4>"
Output:
If you prefer to change the properties using SetMargin(), SetMarginBottom(), etc, instead of CSS properties, make sure you're doing that on the objects you're actually adding to the document.
Related
I'm new to all this kendo stuff i need help in populating kendogrid from a csv file.
The csv data is stored in an array of strings returned by a service.
Data looks like :
0: "Module,LogLevel,LogType,LoggedTime,LogMessage"
1: "00D02D5A4B66 ,CommServer ,Level3 ,Information ,03/16/2015 00:32:57:5716 ,[ISOMMessageHandler::Initialize]-[EventCount:20,ObjectRetryCount:6]"
2: "00D02D5A4B66 ,CommServer ,Level1 ,Information ,03/16/2015 00:32:57:5716 ,ISOMProtocolHandler::HandleConnectGeneric] - Before UpdatePanelTouched - CommServerID : 1, ConnectionMode : 2"
3: "00D02D5A4B66 ,CommServer ,Level4 ,Information ,03/16/2015 00:32:57:5716 ,[PanelDataConfigurationHandler : UpdatePanelConnectionStatus] : CommServerID 1, CommMode : 2"
i need to display 0th indexed data as title of the columns
and rest in cells of the column.
My advice is to make a wrapper method yourself and get it into JSON.
needed wrapper as told by Thomas.
here is my wrapper function
function csvJSON(lines) {
var result = [];
var headers = lines[0].split(",");
headers.unshift("MAC");
for (var i = 1; i < lines.length; i++) {
var obj = {};
var currentline = lines[i].split(",");
for (var j = 0; j < headers.length; j++) {
obj[headers[j]] = currentline[j];
}
result.push(obj);
}
return result;
}
I am using the below code to loop through an XML document in order to get the "food" elements. I want to make sure that when an XML element is added it will be shown in the browser automaticaly as a list item.
var myNodeList = document.getElementsByTagName('food')
for (var i=0; i < myNodeList.length; i++) {
var output = '<ul>';
var food = request.responseXML.getElementsByTagName('food')[i];
I believe I was able to figure it out through the following approach:
var foodList = request.responseXML.getElementsByTagName('food')
for (var i=0; i < foodList.length; i++) {
var output = '<ul>';
var food = request.responseXML.getElementsByTagName('food')[i];
I need to list detailed information about the fonts used in a set of inDesign documents. The information I need is essentially accessible through the menu item Type › Find Fonts… (as explained here) but going through each font in every document and writing down the information is not feasible.
I can find much of the information in the Font objects underdocument.fonts and my question is how to access or generate the extended properties found in the panel below:
Character count for the given font
Pages where the font occurs
Edit: The document.fonts array also doesn't seem to include missing fonts.
Well, here's a brute-force strategy for character counting. It iterates through every character textStyleRange in the document and checks its applied font. Edit: Updated to use textStyleRanges. Much faster than going through every character.
var document = app.open(new File(Folder.desktop.fsName + "/test/test.indd"));
try {
var fontMultiset = countCharsInFonts(document);
// For each font, display its character count.
var fonts = document.fonts.everyItem().getElements();
for (var i = 0; i < fonts.length; i++) {
var fontName = fonts[i].fullName;
$.writeln(fontName + ": " + fontMultiset[fontName]);
}
}
finally {
document.close();
}
function countCharsInFonts(document) {
// Create the font multiset.
var fontMultiset = {
add: function add(fontName, number) {
if (this.hasOwnProperty(fontName)) {
this[fontName] += number;
}
else {
this[fontName] = number;
}
},
};
// For every textStyleRange in the document, add its applied font to the multiset.
var stories = document.stories.everyItem().getElements();
for (var i = 0; i < stories.length; i++) {
var story = stories[i];
var textStyleRanges = story.textStyleRanges.everyItem().getElements();
for (var j = 0; j < textStyleRanges.length; j++) {
fontMultiset.add(textStyleRanges[j].appliedFont.fullName, textStyleRanges[j].length);
}
}
// For any fonts that aren't applied in the document, set the character count to 0.
var fonts = document.fonts.everyItem().getElements();
for (var i = 0; i < fonts.length; i++) {
var fontName = fonts[i].fullName;
if (!fontMultiset.hasOwnProperty(fontName)) {
fontMultiset[fontName] = 0;
}
}
return fontMultiset;
}
i'm using websupergoos abcpdf to convert html pages to pdf via addimageurl.
Works great, but the resulting pdf does not allow the user to select text and copy. All is one 'image'.
Is it possible to do this? Which are the settings to use?
This is my current code. The commented "flatten" does not seem to do anything relevant. The HttpStream simply forewards the pdf to users as a doc.
var doc = new Doc();
doc.HtmlOptions.UseScript = true;
doc.Units = "mm";
doc.MediaBox.String = "0 0 210 297";
doc.Rect.String = doc.MediaBox.String;
doc.Rect.Inset(10.0, 10.0);
doc.SetInfo(0, "License", abcpdfkey);
doc.HtmlOptions.UseScript = true;
doc.HtmlOptions.AddMovies = true;
doc.HtmlOptions.RetryCount = 0;
doc.HtmlOptions.ContentCount = 1;
doc.Page = doc.AddPage();
for (int i = doc.AddImageUrl(url); doc.Chainable(i); i = doc.AddImageToChain(i))
{
doc.Page = doc.AddPage();
}
int pageCount = doc.PageCount;
for (int j = 1; j <= pageCount; j++)
{
doc.PageNumber = j;
// doc.Flatten();
}
this.HttpStream(doc.GetData(), filename);
Before sending the PDF to the HTTP stream, you can set the encryption properties
The CanCopy Property sets if the user can copy text from the PDF
To set it add the following code:
doc.Encryption.CanCopy = true;
You may need to set doc.Encryption.CanExtract as well
I have an editable <iframe> with the some HTML code in it. I need get all <a> tags in my range. I tried this code but it doesn't work:
var select = document.getElementById(iframe_id).contentWindow.getSelection();
var range = select.getRangeAt(0);
//HERE I WANT TO FIND ALL TAGS IN THIS RANGE AND IF IT "A" - ADD NEW ATTRIBUTE "CLASS". SOMETHING LIKE THIS
var parent = rng.commonAncestorContainer;
for(var i=0; i<parent.childNodes.length; i++)
{
if(parent.childNodes[i].tagName.toLowerCase() == "a")
parent.childNodes[i].setAttribute("class", "href_class");
}
You can use getElementsByTagName() to get all <a> tags of the range container and then check for each of them whether it actually belongs to the range using range.compareBoundaryPoints() (only parts of the container might be selected). Something like this:
var links = rng.commonAncestorContainer.getElementsByTagName("a");
for (var i = 0; i < links.length; i++)
{
var linkRange = document.createRange();
linkRange.selectNode(links[i]);
if (rng.compareBoundaryPoints(Range.START_TO_START, linkRange) <= 0 && rng.compareBoundaryPoints(Range.END_TO_END, linkRange) >= 0)
{
links[i].className = "href_class";
}
}
This should get you started in the right direction. This code does not do any null reference checks on the iframe, selection, range or list.
function addAnchorClass(targetFrameId) {
var targetIframe = document.getElementById(targetFrameId).contentWindow;
var selection = targetIframe.getSelection();
var range = selection.getRangeAt(0);
var alist = range.commonAncestorContainer.getElementsByTagName("a");
for (var i=0, item; item = alist[i]; i++) {
if (selection.containsNode(item, true) ) {
item.className += "PUT YOUR CSS CLASS NAME HERE";
}
}
}