ITextSharp export HTML to PDF with bottom-border - itext

I am trying to export the following HTML into a PDF with ITextSharp but the border does not show no matter how many ways I try.
The HTML shows the bottom border but once exported into the PDF it is lost in translation. Any ideas or ways that I can fake the bottom border?
Thanks
HTML:
<Table >
<tr>
<td class="test123">Test</td>
<td>Test</td>
</tr>
<tr>
<td>Test</td>
<td>Test</td>
</tr>
<tr>
<td>Test</td>
<td>Test</td>
</tr>
<tr>
<td>Test</td>
<td>Test</td>
</tr>
<tr>
<td>Test</td>
<td>Test</td>
</tr>
</Table>
C#:
string htmWrite = File.ReadAllText(Server.MapPath("~/Sample/Test.html"));
Document document = new Document();
StyleSheet css = new StyleSheet();
css.LoadStyle("test123", HtmlTags.HR, "1");
css.LoadStyle("test123", "border-bottom-style", "solid");
css.LoadStyle("test123", "border-bottom-width", "2px");
PdfWriter.GetInstance(document, new FileStream(#"C:\test\MySamplePDF.pdf", FileMode.Create));
document.Open();
iTextSharp.text.html.simpleparser.HTMLWorker hw =
new iTextSharp.text.html.simpleparser.HTMLWorker(document);
hw.SetStyleSheet(css);
hw.Parse(new StringReader(htmWrite));
document.Close();

Use XMLWorkerHelper.
The borders should set properly as you need in your HTML file. XMLWorkerHelper automatically takes care of applying that styles. For bottom border use as below:
border-bottom-color: Black;
border-bottom-width : 1px;
border-bottom-style : solid;

Workaround to use XMLWorkerHelper
Document document = new Document();
PdfWriter writer = PdfWriter.GetInstance(document, new FileStream(#"C:\test\MySamplePDF.pdf", FileMode.Create));
document.Open();
TextReader r = new StreamReader(Server.MapPath("~/Sample/Test.html"));
XMLWorkerHelper.GetInstance().ParseXHtml(writer, document, r);document.Close();

Related

how to column span in pdf Table.fromTextArray() function in flutter

How do I create a table using flutter pdf like this
please help me
I am using Table.fromTextArray() function but I can't cut one column or row
you can make table with markdown package
Markdown(
data: '<table>
<tr>
<th>Company</th>
<th>Contact</th>
<th>Country</th>
</tr>
<tr>
<td>Alfreds Futterkiste</td>
<td>Maria Anders</td>
<td>Germany</td>
</tr>
<tr>
<td>Centro comercial Moctezuma</td>
<td>Francisco Chang</td>
<td>Mexico</td>
</tr>
</table>'
)
I think using MD is the easier method

PuppeteerJS - how can I scrape text content from a td element based on the text of the adjacent td?

I am attempting to scrape a link from a td cell adjacent to another td labeling the type or description of the link using puppeteer. There are no classes or id distinguishing these td cells other than the text content
<tr>
<td scope="row">1</td>
<td scope="row">10-Q</td>
<td scope="row">nflx-093018x10qxdoc.htm</td>
<td scope="row">10-Q</td>
<td scope="row">1339833</td>
</tr>
<tr class="blueRow">
<td scope="row">2</td>
<td scope="row">EXHIBIT 31.1</td>
<td scope="row">nflx311_q32018.htm</td>
<td scope="row">EX-31.1</td>
<td scope="row">14914</td>
</tr>
<tr>
<td scope="row">3</td>
<td scope="row">EXHIBIT 31.2</td>
<td scope="row">nflx312_q32018.htm</td>
<td scope="row">EX-31.2</td>
<td scope="row">14553</td>
</tr>
<tr class="blueRow">
<td scope="row">4</td>
<td scope="row">EXHIBIT 32.1</td>
<td scope="row">nflx321_q32018.htm</td>
<td scope="row">EX-32.1</td>
<td scope="row">12406</td>
</tr>
the link after td containing '10Q'
XPath expressions
This is where XPath expression are great:
//td[contains(., '10-Q')]/following-sibling::td[1]/a[1]
This XPath expression queries for a td element containing the text 10-Q. Then it will take the following td element and return the first link (a) inside. Alternatively, you could use //td[text()='10-Q']/ in the beginning, if you don't just want the element to contain the text, but to exactly match it.
Usage within puppeteer
To get the element with puppeteer, use the page.$x function. To extract information (like href) from the queried node, use page.evaluate.
Putting all together, the code looks like this:
const [linkHandle] = await page.$x("//td[contains(., '10-Q')]/following-sibling::td[1]/a[1]");
const address = await page.evaluate(link => link.href, linkHandle);
You can do this with vanila javascript,
// find all tr elements
[...document.querySelectorAll('tr')]
// check which one of them includes the word
.find(e=>e.innerText.includes('10-Q'))
// get the link inside
.querySelector('a')
With puppeteer $eval, this can be simplified,
page.$$eval('tr', eachTr=> eachTr.find(e=>e.innerText.includes('10-Q')).querySelector('a'))
Or page.evaluate,
page.evaluate(()=> {
// find all tr elements
return [...document.querySelectorAll('tr')]
// check which one of them includes the word
.find(e=>e.innerText.includes('10-Q'))
// get the link inside
.querySelector('a')
// do whatever you want to do with this
.href
})
Readable solution.

how to access html element which doesn't have a wicket:id

I am new to wicket ,Please someone help me with a thought. I have a logic around a checkbox to display or not to display.
Problem:
when the logic of not to display a checkbox is on , which is by adding a display:none to the checkbox element dynamcially in code , there is a white space because of td surronding the checkbox.
my html looks like
<span wicket:id="checkgroup">
<table>
<tr wicket:id="srow" >
<td><input type="checkbox" wicket:id="scheck"/></td>
<td><img wicket:id="sicon"></img></td>
</tr>
</table>
</span>
so in code I have if else logic for adding a display:none to check box element which removes the checkbox from the view which looks like the below
<span wicket:id="checkgroup">
<table>
<tr wicket:id="srow" >
<td><input type="checkbox" wicket:id="scheck" style="display:none"/></td>
<td><img wicket:id="sicon"></img></td>
</tr>
</table>
</span>
final CheckGroup<Scope> checkGroup = new CheckGroup<>("checkGroup",
new ArrayList<> ());
ListView<Scope> listView = new ListView<Scope>
("srow", sList);
#Override
protected void populateItem(final ListItem<S> item)
{
Check<S> check = new Check<>("scheck", item.getModel(), checkGroup);
if(defaultscope)
{
check.add(new AttributeModifier("style","display:none"));
}
item.add(check);
}
so now my checkbox disappears but the surrounding td stays and causing a white space in display.
Any ideas on how to approach this issue.
Thanks.
You can use <wicket:enclosure> to remove html if the referenced child is not present. wicket enclosure.
Your code in populateItem could look like this:
Check<S> check = new Check<>("scheck", item.getModel(), checkGroup);
if(defaultscope)
{
check.setVisible(false);
}
item.add(check);
Your markup would look like this:
<tr wicket:id="srow" >
<wicket:enclosure>
<td><input type="checkbox" wicket:id="scheck"/></td>
</wicket:enclosure>
<td><img wicket:id="sicon"></img></td>
</tr>

Populating table with apache wicket

I need to dynamically poplulate a table like this. The problem is, it is not a simple table. It has the "rowspan" characteristics.
For a single entry there are multiple fields entries which are being stored in separate rows.
This is a little tricky to populate with Wicket. Any help , advises, suggestions would be great.
This is what the table looks like on the HTML page:
https://jsfiddle.net/sayrandhri/4ktmy6cn/2/
<table>
<tr>
<th>Name</th>
<th>Role</th>
<th>Company</th>
<th>Request</th>
<th>Change</th>
</tr>
<tr>
<td rowspan=2>ABC</td>
<td rowspan=2>User</td>
<td>Y</td>
<td>True</td>
<td>False</td>
</tr>
<tr>
<td>Telecom</td>
<td>True</td>
<td>False</td>
</tr>
<tr>
<td rowspan=3>XYZ </td>
<td rowspan=3>User</td>
<td>O </td>
<td>False</td>
<td>False</td>
</tr>
<tr>
<td>Q</td>
<td>True</td>
<td>True</td>
</tr>
<tr>
<td>R</td>
<td>False</td>
<td>False</td>
</tr>
</table>
You can try following approach:
HTML:
<table>
<tr>
<th>Name</th>
<th>Role</th>
<th>Company</th>
<th>Request</th>
<th>Change</th>
</tr>
<tbody wicket:id="userList">
<tr wicket:id="providerList">
<td wicket:id="userName"></td>
<td wicket:id="roleName"></td>
<td wicket:id="provider"></td>
<td wicket:id="request"></td>
<td wicket:id="change"></td>
</tr>
</tbody>
</table>
Java:
add(new ListView<User>("userList", new PropertyModel<>(this, "users")) {
#Override
protected void populateItem(ListItem<User> listItem) {
final User user = listItem.getModelObject();
listItem.add(new ListView<Provider>("providerList", user.getProviders()) {
#Override
protected void populateItem(ListItem<Provider> listItem) {
final Provider provider = listItem.getModelObject();
Label nameLabel = new Label("userName", user.getName());
Label roleNameLabel = new Label("roleName", user.getRoleName());
listItem.add(nameLabel);
listItem.add(roleNameLabel);
if (user.getProviders().indexOf(provider) == 0) {
AttributeAppender attributeAppender =
AttributeAppender.append("rowspan", user.getProviders().size());
nameLabel.add(attributeAppender);
roleNameLabel.add(attributeAppender);
} else {
nameLabel.setVisible(false);
roleNameLabel.setVisibilityAllowed(false);
}
listItem.add(new Label("provider", provider.getName()));
listItem.add(new Label("request", provider.isRequest()));
listItem.add(new Label("change", provider.isChange()));
}
});
}
});
Be advised that this way user without any providers wont show up on the list at all.
wicket:container solves this problem.
Your html file would look like this:
<wicket:container wicket:id="doubleRow">
<tr>
...
First Row components
...
</tr>
<tr>
...
Second Row components
...
</tr>
</wicket:container>
Assuming you are using a DataTable with Columns:
In the cell that spans several rows you set the rowspan Attribute with a Model. The value in that model will be increased as long as the value of that cell is not changing.
Once you detect a change in the content, you create a new Model with a rowspan value of 1 and assign that again to the current cell.
Something like this might do it, but I cannot test it at the moment:
private IModel<Integer> currentRowSpanModel = new Model<>(0);
...
new AbstractColumn<Object, String>(new Model<>("ColumnWithRowSpan")) {
#Override
public void populateItem(Item<ICellPopulator<Object>> cellItem, String componentId, IModel<Object> rowModel) {
if (/*Content of cell has changed compared to last row*/) {
// write the content to the cell and add the rowspan Attribute
cellItem.add(new Label(componentId, "Content"));
currentRowSpanModel = new Model<>(1);
cellItem.add(AttributeModifier.replace("rowspan", currentRowSpanModel));
} else {
// Hide cell with same content and instead increase rowspan
cellItem.add(new WebMarkupContainer(componentId));
cellItem.setVisible(false);
currentRowSpanModel.setObject(currentRowSpanModel.getObject()+1);
}
}
}

Setting alignment in verticalpanel - gwt

I am trying to set the align property in vertical panel in GWT like this:
vpanel = new VerticalPanel();
vPanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_LEFT);
and then adding children which gives me a table like this:
<table>
<tbody>
<tr><td align="left"></td></tr>
<tr><td align="left"></td></tr>
</tbody>
</table>
But what I want is
<table align="left">
<tbody>
<tr><td></td></tr>
</tbody>
</table>
I know it's a stupid question but I am stuck with browser compatibility issue and only the HTML specified fixes issue on all browsers. Any ideas?
You can get the underlying element of a widget and set an attribute to it using getElement().setAttribute(..) for instance :
VerticalPanel panel = new VerticalPanel();
panel.getElement().setAttribute("align", "left");
RootPanel.get().add(panel);