Tables truncated with AbcPdf - truncate

I'm using the AbcPdf library to transform an aspx page to a pdf object. I have achieved my goal, but I have a problem. The data in the aspx page is a set of Tables, and they are dynamic, I mean, it can be 2 tables, or 30 or whatever. I have achieved that when the number of tables is bigger than one page, the library creates the required pages, but the problem is that it truncates the table.
Question: Is there any way in the AbcPdf library to not truncate tables or objects when the number of them is bigger than one page?

Here is the sample code that works great:
http://www.websupergoo.com/helppdf7net/source/4-examples/13-pagedhtml.htm
Doc theDoc = new Doc();
theDoc.Rect.Inset(72, 144);
theDoc.Page = theDoc.AddPage();
int theID;
theID = theDoc.AddImageUrl("http://www.yahoo.com/");
while (true) {
theDoc.FrameRect(); // add a black border
if (!theDoc.Chainable(theID))
break;
theDoc.Page = theDoc.AddPage();
theID = theDoc.AddImageToChain(theID);
}
for (int i = 1; i <= theDoc.PageCount; i++) {
theDoc.PageNumber = i;
theDoc.Flatten();
}
theDoc.Save(Server.MapPath("pagedhtml.pdf"));
theDoc.Clear();

Related

How can i retrive and manipulate "chapters" and "subchapters" of a word document based on headings?

A client would like me to build an app or add-in where they can search for a word and display every chapter the word is found in. Then they would like to be able to select chapters and have them exported to a separate document. Basically a document assembler/builder but working just with chapters/sections.
I've looked into the office.js documentation and there doesn't seem to be a way for me to interact with the table of contents or sections based on headings. I guess i could edit the document, remove all sections and add in new ones where a chapter begins, but that would require a lot of manual editing and id like to automate this as much as possible.
My second thought was to grab each heading and the paragraphs until the next heading is hit, but the documentation is a bit sparse and Im not sure what the best way to do that is.
So is there anyway with office.js to cleanly separate chapters/sections?
The following loops over paragraphs and looks for words with the style heading 1 or heading 2 and adds their ranges to headingRanges[].
headingRanges[] is later looped over and a new range, deltaRange, is created by expanding each heading range to the start of the following heading.
I then output the deltaRange's text to console.
This chops up chapters with sub-chapters in them, but if that functionality is necessary it shouldn't be too difficult to build on top of this.
let headings = [];
let headingRanges = [];
Word.run(async context => {
let paragraphs = context.document.body.paragraphs;
context.load(paragraphs, ["items"]);
await context.sync();
for (let i = 0; i < paragraphs.items.length; ++i) {
let item = paragraphs.items[i];
context.load(item, ["text", "style", "styleBuiltIn"]);
await context.sync();
if ( item.style === "heading 1" || item.style === "heading 2"){
//console.log("(" + item.style + ")\n" + item.text);
headings.push(item.text);
let itemRange = item.getRange("start");
itemRange.track();
headingRanges.push(itemRange);
}
}
for(let i = 0; i < headingRanges.length-1; i++){
let deltaRange = headingRanges[i].expandTo(headingRanges[i+1]);
let chapterText = deltaRange.text;
await context.sync();
console.log(chapterText);
}
});
I'm now having issues with keeping track() of ranges and having Word.run() use that ranges context, but ill make a separate post for that.

Is there way to auto resize percentage columns when column group is collapsed/expaned in NatTable

I found ResizeColumnHideShowLayer class at nattable version 1.6.
(about https://bugs.eclipse.org/bugs/show_bug.cgi?id=521486)
That is work fine for normal column headers only.
But, if I collapse a column group, no adjust size to fit window. (no increasing column size)
How can I solve the problem?
Is there way to resize other columns to fit window automatically increase?
Thank you.
Currently not because the ColumnGroupExpandCollapseLayer is taking care of hiding collapsed columns.
I found solution by myself!
It works fine very well. :-)
I was run based on NatTable v1.6 version.(downloaded yesterday)
I think this is a basic feature, so I hope this feature will be included in the next NatTable version.
In narrow tables, behavior that collapsing column group means that may be someone want to view other column data more widely.
Overview (Problem screen and solved screen)
I explain using two application(before, after) screen shot.
Refer to bottom image if you want understand my issue easily at once.
Problem screen
enter image description here
Improved screen
enter image description here
Solution summary :
Add event listener to ColumnGroupExpandCollapseLayer.
      (HideColumnPositionsEvent, ShowColumnPositionsEvent)
Handle above events.
      Get column indices which is hidden by collapsed
      Execute MultiColumnHideCommand with the indices
Layer structure of my test code
↑ ViewportLayer (top layer)
| SelectionLayer
| ColumnGroupExpandCollapseLayer
| ResizeColumnHideShowLayer
| ColumnGroupReorderLayer
| ColumnReorderLayer
| DataLayer (base layer)
Implementation code is below:
void method() {
...
columnGroupExpandCollapseLayer.addLayerListener(new ILayerListener() {
#Override
public void handleLayerEvent(ILayerEvent event) {
boolean doRedraw = false;
//It works for HideColumnPositionsEvent and ShowColumnPositionsEvent
// triggered by ColumnGroupExpandCollapseCommandHandler
if (event instanceof HideColumnPositionsEvent) {
HideColumnPositionsEvent hideEvent = (HideColumnPositionsEvent)event;
Collection<Range> columnPositionRanges = hideEvent.getColumnPositionRanges();
Collection<Integer> convertIntegerCollection = convertIntegerCollection(columnPositionRanges);
int[] positions = convertIntPrimitiveArray(convertIntegerCollection);
//Execute command to hide columns that was hidden by collapsed column group.
MultiColumnHideCommand multiColumnHideCommand = new MultiColumnHideCommand(resizeColumnHideShowLayer, positions);
resizeColumnHideShowLayer.doCommand(multiColumnHideCommand);
doRedraw = true;
}else if (event instanceof ShowColumnPositionsEvent) {//called by ColumnGroupCollapsedCollapseCommandHandler
ShowColumnPositionsEvent showEvent = (ShowColumnPositionsEvent)event;
Collection<Range> columnPositionRanges = showEvent.getColumnPositionRanges();
Collection<Integer> positions = convertIntegerCollection(columnPositionRanges);
//Execute command to show columns that was hidden by expanded column group.
MultiColumnShowCommand multiColumnShowCommand = new MultiColumnShowCommand(positions);
resizeColumnHideShowLayer.doCommand(multiColumnShowCommand);
//Set whether or not to redraw table
doRedraw = true;
}
if (doRedraw) {
natTable.redraw();
}
}
/**
* Merge position values within several Ranges to Integer collection
*/
private Collection<Integer> convertIntegerCollection(Collection<Range> rangeCollection) {
Iterator<Range> rangeIterator = rangeCollection.iterator();
Set<Integer> mergedPositionSet = new HashSet<Integer>();
while (rangeIterator.hasNext()) {
Range range = rangeIterator.next();
mergedPositionSet.addAll(range.getMembers());
}
return mergedPositionSet;
}
/**
* Convert Integer wrapper object to primitive value
*/
private int [] convertIntPrimitiveArray(Collection<Integer> integerCollection) {
Integer [] integers = (Integer [])integerCollection.toArray(new Integer[integerCollection.size()]);
int [] positionPrimitives = new int[integers.length];
for (int i = 0 ; i < integers.length ; i++) {
positionPrimitives[i] = integers[i].intValue();
}
return positionPrimitives;
}
});
}

iTextSharp automatically shrinking images when end of the page reach

I'm using iTextSharp to display images in a pdf report. Here I want display two images in a row and it's working as expected but having a issue when end of the page reaches. The issue is that last row images get shrink to fit in same page, it doesn't automatically add it to the next page. All images having same dimension and resolution.
Please, provide us with the code.
I wrote the test below (although it's in java, there should be no problem) and the results seem to be correct.
public void tableWithImagesTest01() throws IOException, InterruptedException {
String testName = "tableWithImagesTest01.pdf";
String outFileName = destinationFolder + testName;
String cmpFileName = sourceFolder + "cmp_" + testName;
PdfDocument pdfDoc = new PdfDocument(new PdfWriter(outFileName));
Document doc = new Document(pdfDoc, PageSize.A3);
Image image1 = new Image(ImageDataFactory.create(sourceFolder + "itis.jpg"));
Table table = new Table(2);
for (int i = 0; i < 20; i++) {
table.addCell(new Cell().add(image1));
table.addCell(new Cell().add(image1));
table.addCell(new Cell().add(new Paragraph("Hello")));
table.addCell(new Cell().add(new Paragraph("World")));
}
doc.add(table);
doc.close();
Assert.assertNull(new CompareTool().compareByContent(outFileName, cmpFileName, destinationFolder, "diff"));
}
The result pdf looks like this:
Maybe you use summat image1.setAutoScale(true);? Still we need your code to look at.
The easiest solution (considering all images have the same dimension and resolution) would be to manually insert a new page and pagebreak every time you have inserted the maximum number of images to a page.
Taken from a comment below, the solution that works is, on the individual images you need to set:
image.ScaleToFitHeight = false;
Likely to happen when keeping rows together

iText 7 - Dynamic Header

I'm using iText 7 to create a PDF document, with a rather complex header.
This header will show a complex table on the first page and a different table on the remaining pages. This table will contain different information that is passed in and will contain the page number and total number of pages.
I know how to create a header with a table.
I know how to create Page X of Y.
I do not know how to create different headers (different tables with different height) that change on some logic when using iText 7:
If page 1 use Table A, if page > 1 use Table B.
Is there some way to solve this with iText 7? Any help would be appreciated.
Btw:
In iText 5 i solved this and have no problem doing this, but I want to use the latest version of iText (7).
you need to implement IEventHandler and add it as an event listener for adding new page
simple example :
public class PdfEventHandler implements IEventHandler {
#Override
public void handleEvent(Event event) {
PdfDocumentEvent docEvent = (PdfDocumentEvent) event;
PdfDocument pdfDoc = docEvent.getDocument();
PdfPage page = docEvent.getPage();
PdfDocumentEvent docEvent = (PdfDocumentEvent) event;
PdfDocument pdfDoc = docEvent.getDocument();
PdfPage page = docEvent.getPage();
int pageNum = pdfDoc.getPageNumber(page)
if(pageNum> 1 )
//add table1
else
//add Table 2
}
}
and then add this event handler to you document event listener like this
PdfEventHandler handler = new PdfEventHandler();
pdf.addEventHandler(PdfDocumentEvent.START_PAGE, handler);

Change value of widget inside GWT flex table when other widget's value changes?

Ok, so I have a pretty specific and to me quite complicated issue, as I'm a GWT newbie.
I have a GWT flex table, which I use to dynamically add rows, whose cells contain GWT widgets. The row number changes, but the number of columns in static, always 6. Each row contains a cell with a remove button and five cells each with their own textbox.
What I need to do is somehow code a kind of relationship between the textbox in cell 6 of one row and the textbox in cell 5 in the next row (and vice versa).
To illustrate: when something changes in the textbox at [1,6] the content of textbox at [2,5] needs to be overwritten with the same value. If the textbox at [2,5] changes the textbox at [1,6] needs to change as well. I cannot use a button to commit the changes, it needs to happen via onValueChange or Blur or something similar, which doesn't require the user to perform a specific action.
My problem stems mostly from trying to figure out how to address specific cells in the flex table and their content. For the remove button the solution was easy enough with a click event handler, but for this issue I just can't seem to be able to come up with a solution.
Sadly I also cannot provide any of the code which I have up until now, since it's a business secret. I can only give a broad description of the problem like the one above.
EDIT:
Actually, it's probably more a problem of not having much code in terms of this specific problem.
What I have is a flex table, which has initially only the header row. Upon clicking a button below this table the addNewField() method is called, which just contains the creation, setting of default values and adding of the text fields into a new row.
addNewField() {
int rows = flextable.getRowCount();
Button removeBtn = new Button("x");
removeBtn.getElement().setId(Integer.toString(rows));
//then the button's event handler
TextBox name = new TextBox();
name.setText("something");
flextable.setWidget(rows, 0, "name");
//repeat 4 more times with incrementing columns for the other widgets
}
This way I add entire rows of editable TextBoxes. What I need is a way to influence the values of the 6th column TextBox of a chosen row and the 5th column TextBox of chosen row + 1.
EDIT2: I've tried the dirty option just to see how it would go and somehow the compare inside the if breaks the app. The compiler detects a nullpointerexception and I can't even debug it with breakpoints because it fails to compile and won't start. I can't figure out why though. I threw the code directly into the event for testing purposes, so pardon the ugliness.
TextBox bis = new TextBox();
bis.setText(rows + ":10:00");
subs.setWidget(rows, 5, bis);
bis.addValueChangeHandler(new ValueChangeHandler<String>()
{
#Override
public void onValueChange(ValueChangeEvent<String> event)
{
allRows: for (int i = 0; i < subs.getRowCount(); i++)
{
for (int j = 0; j < subs.getCellCount(i); j++)
{
if ( subs.getWidget(i, j) == bis )
{
TextBox widgetAtColumnSix = ((TextBox) subs.getWidget(i, 5));
String text = widgetAtColumnSix.getText();
TextBox widgetAtColumnFiveRowPlusOne = ((TextBox) subs.getWidget(i + 1, 4));
widgetAtColumnFiveRowPlusOne.setText(text);
break allRows;
}
}
}
}
});
EDIT: Since you edited your question and you dont want to use EventBus you could iterate over your FlexTable and set your TextBox value depending on your current rowIndex and cellIndex... Its not nice but it should work:
public class CellWidget extends Composite {
private TextBox nameBox;
public CellWidget() {
FlowPanel flowPanel = new FlowPanel();
Button deleteButton = new Button("x");
nameBox = new TextBox();
nameBox.addValueChangeHandler(new ValueChangeHandler<String>() {
#Override
public void onValueChange(ValueChangeEvent<String> event) {
notifiyTextBox(CellWidget.this, event.getValue());
}
});
flowPanel.add(nameBox);
flowPanel.add(deleteButton);
initWidget(flowPanel);
}
public void setText(String text) {
nameBox.setText(text);
}
}
public void notifiyTextBox(CellWidget source, String string) {
rows: for (int i = 0; i < flextable.getRowCount(); i++) {
columns: for (int j = 0; j < flextable.getCellCount(i); j++) {
if (flextable.getWidget(i, j) == source) {
CellWidget widgetAtColumnSix = ((CellWidget) flextable.getWidget(i, 5));
widgetAtColumnSix.setText(string);
CellWidget widgetAtColumnFiveRowPlusOne = ((CellWidget) flextable.getWidget(i + 1, 4));
widgetAtColumnFiveRowPlusOne.setText(string);
break rows;
}
}
}
}
I still would recommend using an eventbus. To make it even more convenient there is the GWT Event Binder lib, which makes using events a breeze.
So when you change a value in your textbox[2,5] it also fires your CustomEvent. All Widgets, that need to change their textbox value just need to catch...