How do I make ABCPdf to automatically write to a new page when text requires more than 1 page? - dynamic

I deal with dynamic input text, so the pages should be dynamically created. If page 1 is already full, it should write to a new page, so it means I can have page 2, page 3 and so on depending on the data processed.
Currently, my text is truncated. Only writes Page 1, the rest of data are not written.
My current code below:
//add page 1
theDoc.Page = theDoc.AddPage();
theDoc.AddImageHtml(html, true, 826, true);
//continue adding page if needed
while (theDoc.GetInfo(theID, "Truncated") == "1")
{
theDoc.Page = theDoc.AddPage();
theDoc.AddImageHtml(html, true, 826, true);
}
//save file
String pdfFilePath = WebConfigurationManager.AppSettings["pdfFilePath"];
Guid fileName = Guid.NewGuid();
pdfLink = pdfFilePath + fileName.ToString() + ".pdf";
theDoc.Save(pdfLink);
theDoc.Clear();
variable html contains all the data(webpage), I'm probably missing something in my while loop. Any help is appreciated! Thanks

Found it, Use Chainable and then Flatten()
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();
}

Related

Adobe illustrator linked file name to a layer name script

I want the layer enter image description here
to have the name of the linked file without .eps at the end.
Anyway, I found an answer. So for anyone looking here it is, although it does take to click on every layer, at least you don't have to type it.
function test() {
var sel_itemPlaced = app.activeDocument.selection[0]; // be sure that a linked item (and not an embedded) is selected
var fileName = sel_itemPlaced.file.name;
var textContents = fileName.replace(/\%20/g, " "); //change %20 to spaces
textContents = textContents.replace(/\.[^\.]*$/, ""); //remove extension
var _item = sel_itemPlaced;
while (_item.parent.typename != 'Layer') {
_item = _item.parent;
}
_item.parent.name = textContents;
}
test();
It does work for all placed images and all layers at once:
var images = app.activeDocument.placedItems;
for (var i=0; i<images.length; i++)
images[i].layer.name = images[i].file.name.replace(/\.[^\.]+$/, "");

Expert Pdf - add footer on all pages except on the first page

I am using Expert PDF to generate PDF from HTML.
I have to generate footer on all pages except on the first page.
I tried with:
PdfConverter pdfConverter = new PdfConverter();
AddFooter(pdfConverter);
private void AddFooter(PdfConverter pdfConverter)
{
string thisPageURL = HttpContext.Current.Request.Url.AbsoluteUri;
string headerAndFooterHtmlUrl = thisPageURL.Substring(0, thisPageURL.LastIndexOf('/')) + "/HeaderAndFooterHtml.htm";
//enable footer
pdfConverter.PdfDocumentOptions.ShowFooter = true;
// set the footer height in points
pdfConverter.PdfFooterOptions.FooterHeight = 60;
//write the page number
pdfConverter.PdfFooterOptions.TextArea = new TextArea(0, 30, "This is page &p; of &P; ",
new System.Drawing.Font(new System.Drawing.FontFamily("Times New Roman"), 10, System.Drawing.GraphicsUnit.Point));
pdfConverter.PdfFooterOptions.TextArea.EmbedTextFont = true;
pdfConverter.PdfFooterOptions.TextArea.TextAlign = HorizontalTextAlign.Right;
// set the footer HTML area
pdfConverter.PdfFooterOptions.HtmlToPdfArea = new HtmlToPdfArea(0, 0, -1, pdfConverter.PdfFooterOptions.FooterHeight,
headerAndFooterHtmlUrl, 1024, -1);
pdfConverter.PdfFooterOptions.HtmlToPdfArea.FitHeight = true;
}
but this code generate footer on all pages.
Can someone give me idea or solution for this problem?
Thanks in advance!
Add below line in your code:
pdfConverter.PdfFooterOptions.ShowOnFirstPage = false;

ColdFusion CFDOCUMENT with links to other PDFs

I am creating a PDF using the cfdocument tag at the moment. The PDF is not much more than a bunch of links to other PDFs.
So I create this PDF index and the links are all HREFs
Another PDF
if I set the localURL attribute to "no" my URLs have the whole web path in them:
Another PDF
if I set the localURL attribute to "yes" then I get:
Another PDF
So this index PDF is going to go onto a CD and all of the linked PDFs are going to sit right next to it so I need a relative link ... more like:
Another PDF
cfdocument does not seem to do this. I can modify the file name of the document and make it "File:///Another_PDF.pdf" but this does not work either because I don't know the driveletter of the CD drive ... or if the files are going to end up inside a directory on the CD.
Is there a way (possibly using iText or something) of opening up the PDF once it is created and converting the URL links to actual PDF GoTo tags?
I know this is kind of a stretch but I am at my wits end with this.
So I've managed to get into the Objects but I'm still struggling with.
Converting from:
5 0 obj<</C[0 0 1]/Border[0 0 0]/A<</URI(File:///75110_002.PDF)/S/URI>>/Subtype/Link/Rect[145 502 184 513]>>endobj
To this:
19 0 obj<</SGoToR/D[0/XYZ null null 0]/F(75110_002.PDF)>>endobj
20 0 obj<</Subtype/Link/Rect[145 502 184 513]/Border[0 0 0]/A 19 0 R>>endobj
Wow this is really kicking my ass! :)
So I've managed to get the document open, loop through the Link Annotations, capture the Rect co-ordinates and the linked to document name (saved into an array of Structures) and then successfully deleted the Annotation which was a URI Link.
So now I thought I could now loop over that array of structures and put the Annotations back into the document using the createLink method or the setAction method. But all the examples I've seen of these methods are attached to a Chunk (of text). But my document already has the Text in place so I don't need to remake the text links I just need to put the Links back in in the same spot.
So I figured I could reopen the document and look for the actual text that was the link and then attache the setAction to th ealready existing chunk of text .... I can't find the text!!
I suck! :)
This thread has an example of updating the link actions, by modifying the pdf annotations. It is written in iTextSharp 5.x, but the java code is not much different.
The thread provides a solid explanation of how annotations work. But to summarize, you need to read in your source pdf and loop through the individual pages for annotations. Extract the links and use something like getFileFromPath() to replace them with a file name only.
I was curious, so I did a quick and ugly conversion of the iTextSharp code above. Disclaimer, it is not highly tested:
/**
Usage:
util = createObject("component", "path.to.ThisComponent");
util.fixLinks( "c:/path/to/sourceFile.pdf", "c:/path/to/newFile.pdf");
*/
component {
/**
Convert all absolute links, in the given pdf, to relative links (file name only)
#source - absolute path to the source pdf file
#destination - absolute path to save copy
*/
public function fixLinks( string source, string destination) {
// initialize objects
Local.reader = createObject("java", "com.lowagie.text.pdf.PdfReader").init( arguments.source );
Local.pdfName = createObject("java", "com.lowagie.text.pdf.PdfName");
// check each page for hyperlinks
for ( Local.i = 1; Local.i <= Local.reader.getNumberOfPages(); Local.i++) {
//Get all of the annotations for the current page
Local.page = Local.reader.getPageN( Local.i );
Local.annotations = Local.page.getAsArray( Local.PdfName.ANNOTS ).getArrayList();
// search annotations for links
for (Local.x = 1; !isNull( Local.annotations) && Local.x < arrayLen(Local.annotations); Local.x++) {
// get current properties
Local.current = Local.annotations[ Local.x ];
Local.dictionary = Local.reader.getPdfObject( Local.current );
Local.subType = Local.dictionary.get( Local.PdfName.SUBTYPE );
Local.action = Local.dictionary.get( Local.PdfName.A );
Local.hasLink = true;
//Skip this item if it does not have a link AND action
if (Local.subType != Local.PdfName.LINK || isNull(Local.action)) {
Local.hasLink = false;
}
//Skip this item if it does not have a URI
if ( Local.hasLink && Local.action.get( Local.PdfName.S ) != Local.PdfName.URI ) {
Local.hasLink = false;
}
//If it is a valid URI, update link
if (Local.hasLink) {
// extract file name from URL
Local.oldLink = Local.action.get( Local.pdfName.URI );
Local.newLink = getFileFromPath( Local.oldLink );
// replace link
// WriteDump("Changed link from ["& Local.oldLink &"] ==> ["& Local.newLink &"]");
Local.pdfString = createObject("java", "com.lowagie.text.pdf.PdfString");
Local.action.put( Local.pdfName.URI, Local.pdfString.init( Local.newLink ) );
}
}
}
// save all pages to new file
copyPDF( Local.reader , arguments.destination );
}
/**
Copy all pages in pdfReader to the given destination file
#pdfReader - pdf to copy
#destination - absolute path to save copy
*/
public function copyPDF( any pdfReader, string destination) {
try {
Local.doc = createObject("java", "com.lowagie.text.Document").init();
Local.out = createObject("java", "java.io.FileOutputStream").init( arguments.destination );
Local.writer = createObject("java", "com.lowagie.text.pdf.PdfCopy").init(Local.doc, Local.out);
// open document and save individual pages
Local.doc.open();
for (Local.i = 1; i <= arguments.pdfReader.getNumberOfPages(); Local.i++) {
Local.writer.addPage( Local.writer.getImportedPage( arguments.pdfReader, Local.i) );
}
Local.doc.close();
}
finally
{
// cleanup
if (structKeyExists(Local, "doc")) { Local.doc.close(); }
if (structKeyExists(Local, "writer")) { Local.writer.close(); }
if (structKeyExists(Local, "out")) { Local.out.close(); }
}
}
}
I finally got it:
public function resetLinks( string source, string destination) {
try {
// initialize objects
Local.reader = createObject("java", "com.lowagie.text.pdf.PdfReader").init( arguments.source );
Local.pdfName = createObject("java", "com.lowagie.text.pdf.PdfName");
Local.annot = createObject("java", "com.lowagie.text.pdf.PdfAnnotation");
Local.out = createObject("java", "java.io.FileOutputStream").init( arguments.destination );
Local.stamper = createObject("java", "com.lowagie.text.pdf.PdfStamper").init(Local.reader, Local.out);
Local.PdfAction = createObject("java", "com.lowagie.text.pdf.PdfAction");
Local.PdfRect = createObject("java", "com.lowagie.text.Rectangle");
Local.PdfBorderArray = createObject("java", "com.lowagie.text.pdf.PdfBorderArray").init(javacast("float", "0"), javacast("float", "0"), javacast("float", "0"));
Local.newAnnots = [];
// check each page for hyperlinks
// Save the data to a structure then write it to an array
// then delete the hyperlink Annotation
for ( Local.i = 1; Local.i <= Local.reader.getNumberOfPages(); Local.i = Local.i + 1) {
//Get all of the annotations for the current page
Local.page = Local.reader.getPageN( Local.i );
Local.annotations = Local.page.getAsArray( Local.PdfName.ANNOTS ).getArrayList();
// search annotations for links
for (Local.x = arrayLen(Local.annotations); !isNull( Local.annotations) && Local.x > 0; Local.x--) {
// get current properties
Local.current = Local.annotations[ Local.x ];
Local.dictionary = Local.reader.getPdfObject( Local.current );
Local.subType = Local.dictionary.get( Local.PdfName.SUBTYPE );
Local.action = Local.dictionary.get( Local.PdfName.A );
Local.hasLink = true;
//Skip this item if it does not have a link AND action
if (Local.subType != Local.PdfName.LINK || isNull(Local.action)) {
Local.hasLink = false;
}
//Skip this item if it does not have a URI
if ( Local.hasLink && Local.action.get( Local.PdfName.S ) != Local.PdfName.URI ) {
Local.hasLink = false;
}
//If it is a valid URI, update link
if (Local.hasLink) {
// extract file name from URL
Local.oldLink = Local.action.get( Local.pdfName.URI );
Local.newLink = getFileFromPath( Local.oldLink );
Local.Rect = Local.dictionary.Get(PdfName.Rect);
arrayStruct = StructNew();
arrayStruct.rectSTR = Local.Rect.toString();
arrayStruct.link = Local.newLink;
arrayStruct.page = Local.i;
ArrayAppend(Local.newAnnots, arrayStruct);
// Delete
Local.annotations.remove(Local.current);
}
}
}
// Now really remove them!
Local.reader.RemoveUnusedObjects();
// Now loop over the saved annotations and put them back!!
for ( Local.z = 1; Local.z <= ArrayLen(Local.newAnnots); Local.z++) {
// Parse the rect we got save into an Array
theRectArray = ListToArray(ReplaceNoCase(ReplaceNoCase(Local.newAnnots[z].rectSTR, "[", ""), "]", ""));
// Create the GoToR action
theAction = Local.PdfAction.gotoRemotePage(javacast("string", '#Local.newAnnots[z].link#'), javacast("string", '#Local.newAnnots[z].link#'), javacast("boolean", "false"), javacast("boolean", "false"));
// Create the Link Annotation with the above Action and the Rect
theAnnot = Local.annot.createLink(Local.stamper.getWriter(), Local.PdfRect.init(javacast("int", theRectArray[1]), javacast("int", theRectArray[2]), javacast("int", theRectArray[3]), javacast("int", theRectArray[4])), Local.annot.HIGHLIGHT_INVERT, theAction);
// Remove the border the underlying underlined text will flag item as a link
theAnnot.setBorder(Local.PdfBorderArray);
// Add the Annotation to the Page
Local.stamper.addAnnotation(theAnnot, Local.newAnnots[z].page);
}
}
finally {
// cleanup
if (structKeyExists(Local, "reader")) { Local.reader.close(); }
if (structKeyExists(Local, "stamper")) { Local.stamper.close(); }
if (structKeyExists(Local, "out")) { Local.out.close(); }
}
}
I couldn't have done this without the help of Leigh!!

Split PDF into separate files based on text

I have a large single pdf document which consists of multiple records. Each record usually takes one page however some use 2 pages. A record starts with a defined text, always the same.
My goal is to split this pdf into separate pdfs and the split should happen always before the "header text" is found.
Note: I am looking for a tool or library using java or python. Must be free and available on Win 7.
Any ideas? AFAIK imagemagick won't work for this. May itext do this? I never used and it's
pretty complex so would need some hints.
EDIT:
Marked Answer led me to solution. For completeness here my exact implementation:
public void splitByRegex(String filePath, String regex,
String destinationDirectory, boolean removeBlankPages) throws IOException,
DocumentException {
logger.entry(filePath, regex, destinationDirectory);
destinationDirectory = destinationDirectory == null ? "" : destinationDirectory;
PdfReader reader = null;
Document document = null;
PdfCopy copy = null;
Pattern pattern = Pattern.compile(regex);
try {
reader = new PdfReader(filePath);
final String RESULT = destinationDirectory + "/record%d.pdf";
// loop over all the pages in the original PDF
int n = reader.getNumberOfPages();
for (int i = 1; i < n; i++) {
final String text = PdfTextExtractor.getTextFromPage(reader, i);
if (pattern.matcher(text).find()) {
if (document != null && document.isOpen()) {
logger.debug("Match found. Closing previous Document..");
document.close();
}
String fileName = String.format(RESULT, i);
logger.debug("Match found. Creating new Document " + fileName + "...");
document = new Document();
copy = new PdfCopy(document,
new FileOutputStream(fileName));
document.open();
logger.debug("Adding page to Document...");
copy.addPage(copy.getImportedPage(reader, i));
} else if (document != null && document.isOpen()) {
logger.debug("Found Open Document. Adding additonal page to Document...");
if (removeBlankPages && !isBlankPage(reader, i)){
copy.addPage(copy.getImportedPage(reader, i));
}
}
}
logger.exit();
} finally {
if (document != null && document.isOpen()) {
document.close();
}
if (reader != null) {
reader.close();
}
}
}
private boolean isBlankPage(PdfReader reader, int pageNumber)
throws IOException {
// see http://itext-general.2136553.n4.nabble.com/Detecting-blank-pages-td2144877.html
PdfDictionary pageDict = reader.getPageN(pageNumber);
// We need to examine the resource dictionary for /Font or
// /XObject keys. If either are present, they're almost
// certainly actually used on the page -> not blank.
PdfDictionary resDict = (PdfDictionary) pageDict.get(PdfName.RESOURCES);
if (resDict != null) {
return resDict.get(PdfName.FONT) == null
&& resDict.get(PdfName.XOBJECT) == null;
} else {
return true;
}
}
You can create a tool for your requirements using iText.
Whenever you are looking for code samples concerning (current versions of) the iText library, you should consult iText in Action — 2nd Edition the code samples from which are online and searchable by keyword from here.
In your case the relevant samples are Burst.java and ExtractPageContentSorted2.java.
Burst.java shows how to split one PDF in multiple smaller PDFs. The central code:
PdfReader reader = new PdfReader("allrecords.pdf");
final String RESULT = "record%d.pdf";
// We'll create as many new PDFs as there are pages
Document document;
PdfCopy copy;
// loop over all the pages in the original PDF
int n = reader.getNumberOfPages();
for (int i = 0; i < n; ) {
// step 1
document = new Document();
// step 2
copy = new PdfCopy(document,
new FileOutputStream(String.format(RESULT, ++i)));
// step 3
document.open();
// step 4
copy.addPage(copy.getImportedPage(reader, i));
// step 5
document.close();
}
reader.close();
This sample splits a PDF in single-page PDFs. In your case you need to split by different criteria. But that only means that in the loop you sometimes have to add more than one imported page (and thus decouple loop index and page numbers to import).
To recognize on which pages a new dataset starts, be inspired by ExtractPageContentSorted2.java. This sample shows how to parse the text content of a page to a string. The central code:
PdfReader reader = new PdfReader("allrecords.pdf");
for (int i = 1; i <= reader.getNumberOfPages(); i++) {
System.out.println("\nPage " + i);
System.out.println(PdfTextExtractor.getTextFromPage(reader, i));
}
reader.close();
Simply search for the record start text: If the text from page contains it, a new record starts there.
Apache PDFBox has a PDFSplit utility that you can run from the command-line.
If you like Python, there's a nice library: PyPDF2. The library is pure python2, BSD-like license.
Sample code:
from PyPDF2 import PdfFileWriter, PdfFileReader
input1 = PdfFileReader(open("C:\\Users\\Jarek\\Documents\\x.pdf", "rb"))
# analyze pdf data
print input1.getDocumentInfo()
print input1.getNumPages()
text = input1.getPage(0).extractText()
print text.encode("windows-1250", errors='backslashreplacee')
# create output document
output = PdfFileWriter()
output.addPage(input1.getPage(0))
fout = open("c:\\temp\\1\\y.pdf", "wb")
output.write(fout)
fout.close()
For non coders PDF Content Split is probably the easiest way without reinventing the wheel and has an easy to use interface: http://www.traction-software.co.uk/pdfcontentsplitsa/index.html
hope that helps.

How to get output of a webpage in ActionScript 2

For Actionscript 2.0
Let's say this page
www.example.com/mypage
returns some html that I want to parse in Actionscript.
How do i call this page from Actionscript while getting back the response in a string variable?
use LoadVars():
var lv = new LoadVars();
//if you want to pass some variables, then:
lv.var1 = "BUTTON";
lv.var2 = "1";
lv.sendAndLoad("http://www.example.com/mypage.html", lv, "POST");
lv.onLoad = loadedDotNetVars;
function loadedDotNetVars(success)
{
if(success)
{
// operation was a success
trace(lv.varnameGotFromPage)
}
else
{
// operation failed
}
}
//if you dont want to send data, just get from it, then use just lv.Load(...) instead of sendAndLoad(...)
I understand. Use this code then:
docXML = new XML(msg);
XMLDrop = docXML.childNodes;
XMLSubDrop = XMLDrop[0].childNodes;
_root.rem_x = (parseInt(XMLSubDrop[0].firstChild));
_root.rem_y = (parseInt(XMLSubDrop[1].firstChild));
_root.rem_name = (XMLSubDrop[2].firstChild);
var htmlFetcher:LoadVars = new LoadVars();
htmlFetcher.onData = function(thedata) {
trace(thedata); //thedata is the html code
};
Use:
htmlFetcher.load("http://www.example.com/mypage");
to call.
I suppose you could use:
page = getURL("www.example.com/mypage.html");
And it would load the page contents on the page variable.