Adobe pdf printer doesn't creating the pdf file - pdf

I'm creating an add-in in Revit 2017. The addin will export drawing sheets to PDF files. So, whenever I try to export the sheet a dialog box appears to choose the location to save. I tried to turn off the Prompting programmatically by adding a key to the Windows registry (as described in Adobe documentation page 15-16).
Now, the prompting got turned off and now I'm facing an issue. The issue is the Adobe Printer got stuck while creating the pdf file. See the below image: The PDF creating progress bar seems frozen, I waited for more than 10 mins and it didn't create the pdf file.
Can anybody provide any fix?
Appreciate any suggestion.
Edit
here's the code that I've written for this purpose. I hope this may help to identify the problem.
public static bool ExportSheetToPDF(Document doc, string path)
{
using (Transaction tx = new Transaction(doc)
{
tx.Start("Exportint to PDF");
PrintManager pm = doc.PrintManager;
pm.SelectNewPrintDriver("Adobe PDF");
pm.Apply();
pm.PrintRange = PrintRange.Current;
pm.Apply();
pm.CombinedFile = true;
pm.Apply();
pm.PrintToFile = true;
pm.Apply();
pm.PrintToFileName = path + #"\PDF\" + "abc.pdf";
pm.Apply();
SuppressAdobeDialogAndSaveFilePath(path + #"\PDF\" + "abc.pdf");
pm.SubmitPrint();
pm.Apply();
tx.Commit();
}
return true;
}
// Add Registry Key to suppress the dialog box
public static void SuppressAdobeDialogAndSaveFilePath(string value)
{
var valueName = #"C:\Program Files\Autodesk\Revit 2017\Revit.exe";
var reg = currentUser.OpenSubKey(key, true);
var tempReg = reg.OpenSubKey(valueName);
if (tempReg == null)
{
reg = reg.CreateSubKey(valueName);
}
reg.SetValue(valueName, value);
reg.Close();
}

I have explained how you can achieve this by overriding the registry key for Revit.exe process that Adobe uses to generate the next print.
http://archi-lab.net/printing-pdfs-from-revit-why-is-it-so-hard/
Please remember that you still have to print via Revit PrintManager, but then you can set the registry keys before every print to control where the files get saved.

Related

Aspose.Words save Word document as pdf loses formatting

I am using Aspose.Words for .NET to replace some merge fields in my document and then save the file as a PDF, however, my formatting is getting messed up (even for non-merge fields) by the conversion to PDF (refer to the images). The code is quite simple so I don't see what I'm missing.
The word document, pre-processing:
The generated pdf:
As you can see some of the fields are indented a bit more instead of being nicely aligned.
My code for generating the PDF and replacing the merge fields is:
public async Task<Stream> GenerateContractAsync(string requestRegistrationId)
{
var requestRegistration = await _requestRegistrationRepository
.FindRequestRegistration(requestRegistrationId)
.Include(rr => rr.Request.QualityType)
.Include(rr => rr.User)
.SingleOrDefaultAsync();
var file = await _fileService
.LoadFileAsync("Concept contract.docx");
var user = requestRegistration.User;
var document = new Aspose.Words.Document(file);
document.MailMerge.Execute(
new[]
{
"EmployeeName", "EmployeeDateOfBirth", "EmployeePlaceOfBirth", "EmployeeSSN", "EmployeeCity",
"EmployeeAddress", "ContractStartDate", "EmployeeFunction", "HourlyWage", "WageDeductionApplied"
},
new object[]
{
user.FullName, $"{user.Birthday:dd-MM-yyyy}", "Oss", user.Bsn, user.City,
$"{user.PostalCode}, {user.City}", $"{requestRegistration.Request.StartDate:dd-MM-yyyy}",
requestRegistration.Request.QualityType.Name, $"{requestRegistration.Request.HourlyRate:C}",
user.PayrollTaxDiscountEnabled ? "Ja" : "Nee"
}
);
var mergedDocumentStream = new MemoryStream();
document.Save(mergedDocumentStream, SaveFormat.Pdf);
#if DEBUG
mergedDocumentStream.Seek(0, SeekOrigin.Begin);
await _fileService.SaveFileToDiskAsync($"{user.Id}-{DateTimeOffset.Now:g}.pdf", "", mergedDocumentStream);
#endif
mergedDocumentStream.Seek(0, SeekOrigin.Begin);
return mergedDocumentStream;
}
Any help would be greatly appreciated.
The problem occurs because of missing fonts. Please refer to the following article for details.
How Aspose.Words Uses True Type Fonts
In your case, you need to install 'Verdana', 'Arial' and 'Cambria' fonts on the machine where you are executing this Aspose.Words' code. Simply copying these font files from Windows machine to other MAC machine should work.
I work with Aspose as Developer Evangelist.

How to clean existing properties and replace with metadata template on Photoshop (scripting)?

While creating a script that would automate all the different tasks I do when I start working on a new picture on Photoshop, I encountered the following problem.
Manually, I would Ctrl + Alt + Shift + I, click on the template I want and choose the option "Clear existing properties and replace with template properties".
I can't find the way to do precisely this. The best thing I managed to find is something like this :
app.activeDocument.info.author = "test";
app.activeDocument.info.caption = "";
app.activeDocument.info.captionWriter = "";
app.activeDocument.info.headline = "";
app.activeDocument.info.instructions = "";
app.activeDocument.info.keywords = "";
app.activeDocument.info.authorPosition = "";
app.activeDocument.info.credit = "";
app.activeDocument.info.source = "";
app.activeDocument.info.category = "";
app.activeDocument.info.supplementalCategories = "";
app.activeDocument.info.title = "";
// etc.
And it actually doesn't really work like the "Clear existing properties and replace with template properties".
I didn't find anything on the Photoshop scripting guide, nor on the internet. Any help would be greatly appreciated !
What I think is the problem is Photoshop separates file-metadata from its activeDocument-metadata. What you see in "File info..." (via Ctrl+Alt+Shift+I) is supposed to represent the file in the filesystem, which metadata is embedded in.
There are several scripting guides to Photoshop scripting. I think the one relevant for you would be "Javascript Tools Guide", specifically the chapter 10 "Scripting Access to XMP Metadata".
Is it important for you to set up the metadata already when creating a new picture? If not, you may want to look at a solution using a customized export script.
It customizes XMP-metadata upon exporting like
Create a basic metadata object:
var meta = new XMPMeta();
Provide a namespaceURI (see XMP specs) known to photoshop along with tag name, and value:
meta.setProperty(XMPConst.NS_XMP, "CreatorTool", app.version);
Save the image temporarily (using other script):
var imgFile = new File(fileName);
saveImage(fileName);
Finish saving by adding the metadata-object:
var metaFile = new XMPFile(imgFile.fsName, XMPConst.FILE_UNKNOWN, XMPConst.OPEN_FOR_UPDATE);
if (metaFile.canPutXMP(meta)) { metaFile.putXMP(meta); }
metaFile.closeFile(XMPConst.CLOSE_UPDATE_SAFELY);
Doing it this way also erases any existing or default metadata.

How to check multiple PDF files for annotations/comments?

Problem: I routinely receive PDF reports and annotate (highlight etc.) some of them. I had the bad habit of saving the annotated PDFs together with the non-annotated PDFs. I now have hundreds of PDF files in the same folder, some annotated and some not. Is there a way to check every PDF file for annotations and copy only the annotated ones to a new folder?
Thanks a lot!
I'm on Win 7 64bit, I have Adobe Acrobat XI installed and I'm able to do some beginner coding in Python and Javascript
Please ignore the following suggestion, since the answers already solved the problem.
EDIT: Following Mr. Wyss' suggestion, I created the following code for Acrobat's Javascript console to be run only once at the beginning:
counter = 1;
// Open a new report
var rep = new Report();
rep.size = 1.2;
rep.color = color.blue;
rep.writeText("Files WITH Annotations");
Then this code should be applied to all PDFs:
this.syncAnnotScan();
annots = this.getAnnots();
path = this.path;
if (annots) {
rep.color = color.black;
rep.writeText(" ");
rep.writeText(counter.toString()+"- "+path);
rep.writeText(" ");
if (counter% 20 == 0) {
rep.breakPage();
}
counter++;
}
And, at last, one code to be run only once at the end:
//Now open the report
var docRep = rep.open("files_with_annots.pdf");
There are two problems with this solution:
1. The "Action Wizard" seems to always apply the same code afresh to each PDF (that means that the "counter" variable, for instance, is meaningless; it will always be = 1. But more importantly, var "rep" will be unassigned when the middle code is run on different PDFs).
2. How can I make the codes that should be run only once run only at the beginning or at the end, instead of running everytime for every single PDF (like it does by default)?
Thank you very much again for your help!
This would be possible using the Action Wizard to put together an action.
The function to determine whether there are annotations in the document would be done in Acrobat JavaScript. Roughly, the core function would look like this:
this.syncAnnotScan() ; // updates all annots
var myAnnots = this.getAnnots() ;
if (myAnnots != null) {
// do something if there are annots
} else {
// do something if there are no annots
}
And that should get you there.
I am not completely positive, but I think there is also a Preflight check which tells you whether there are annotations in the document. If so, you would create a Preflight droplet, which would sort out the annotated and not annotated documents.
Mr. Wyss is right, here's a step-by-step guide:
In Acrobat XI Pro, go to the 'Tools' panel on the right side
Click on the 'Action Wizard' tab (you must first make it visible, though)
Click on 'Create New Action...', choose 'More tools' > 'Execute Javascript' and add it to right-hand pane > click on 'Execute Javascript' > 'Specify Settings' (uncheck 'prompt user' if you want) > paste this code:
.
this.syncAnnotScan();
var annots = this.getAnnots();
var fname = this.documentFileName;
fname = fname.replace(",", ";");
var errormsg = "";
if (annots) {
try {
this.saveAs({
cPath: "/c/folder/"+fname,
bPromptToOverwrite: false //make this 'true' if you want to be prompted on overwrites
});
} catch(e) {
for (var i in e)
{errormsg+= (i + ": " + e[i]+ " / ");}
app.alert({
cMsg: "Error! Unable to save the file under this name ('"+fname+"'- possibly an unicode string?) See this: "+errormsg,
cTitle: "Damn you Acrobat"
});
}
;}
annots = 0;
Save and run it! All your annotated PDFs will be saved to 'c:\folder' (but only if this folder already exists!)
Be sure to enable first Javascript in 'Edit' > 'Preferences...' > 'Javascript' > 'Enable Acrobat Javascript'.
VERY IMPORTANT: Acrobat's JS has a bug that doesn't allow Docs to be saved with commas (",") in their names (e.g., "Meeting with suppliers, May 11th.pdf" - this will get an error). Therefore, I substitute in the code above all "," for ";".

Hyperlink Detection from PDF

I have some PDFs containing Hyperlinks both in form of URL and mailto. Now Is there any way or tool(may be 3rd party) to extract the Hyperlink meta information form the PDF like coordinates, link type and destination address. Any help is highly appreciated.
I have already tried with iText and PDFBox but with no major success, even some third party software are not providing me the desired output.
I have tried the following code in Java using iText
PdfReader myReader = new PdfReader("pdf File Path");
PdfDictionary pageDict = myReader.getPageN(1);
PdfArray annots = pageDict.getAsArray(PdfName.ANNOTS);
System.out.println(annots);
ArrayList<String> dests = new ArrayList<String>();
if(annots != null)
{
for(int i=0; i<annots.size(); ++i)
{
PdfDictionary annotDict = annots.getAsDict(i);
PdfName subType = annotDict.getAsName(PdfName.SUBTYPE);
if (subType != null && PdfName.LINK.equals(subType))
{
PdfDictionary action = annotDict.getAsDict(PdfName.A);
if(action != null && PdfName.URI.equals(action.getAsName(PdfName.S)))
{
dests.add(action.getAsString(PdfName.URI).toString());
} // else { its an internal link }
}
}
}
System.out.println(dests);
You can use Docotic.Pdf library for links extraction (disclaimer: I work for the company).
Below is the code that opens specified file, finds all hyperlinks, collects information about position of each link and draws rectangle around each links.
After that the code creates new PDF (with links in rectangles) and a text file with collected information. In the end, both created files are opened in default viewers.
public static void ListAndHighlightLinks(string inputFile, string outputFile, string outputTxt)
{
using (PdfDocument doc = new PdfDocument(inputFile))
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < doc.Pages.Count; i++)
{
PdfPage page = doc.Pages[i];
foreach (PdfWidget widget in page.Widgets)
{
PdfActionArea actionArea = widget as PdfActionArea;
if (actionArea == null)
continue;
PdfUriAction linkAction = actionArea.Action as PdfUriAction;
if (linkAction == null)
continue;
Uri url = linkAction.Uri;
PdfRectangle rect = actionArea.BoundingBox;
// add information about found link into string buffer
sb.Append("Page ");
sb.Append(i.ToString());
sb.Append(" : ");
sb.Append(rect.ToString());
sb.Append(" ");
sb.AppendLine(url.ToString());
// draw rectangle around found link
page.Canvas.DrawRectangle(rect);
}
}
// save document with highlighted links and text information about links to files
doc.Save(outputFile);
System.IO.File.WriteAllText(outputTxt, sb.ToString());
// open created PDF and text file in default viewers
System.Diagnostics.Process.Start(outputTxt);
System.Diagnostics.Process.Start(outputFile);
}
}
You can use the sample code with a call like this:
ListAndHighlightLinks("input.pdf", "output.pdf", "links.txt");
if your pdfs are copy protected, you need to start with step 1, if they're free to copy, you can start with step 2
step 1: convert your pdfs into word .doc: use Adobe Acrobat Pro or an online pdf to word converter:
http://www.pdfonline.com/pdf2word/index.asp
step 2: copy-paste the whole document into the input window here, you can also download the lightweight html tool:
http://www.surf7.net/services/value-added-services/free-web-tools/email-extractor-lite/
select 'url' as 'Type of address to extract', select your separator, hit extract and that's it.
Hope it works cheers.
One possibility would be using a custom JavaScript in Acrobat, which would enumerate the "words" on the page and then read out their Quads. From that you get the coordinates to create a link (or to compare with the links on the page), as well as the actual text (that's the "word(s)".
If it is "only" to set the border of the existing links, you also do another Acrobat JavaScript which enumerates the links of the document, and set their border color property (and you may need to set the width as well).
(if you prefer "buy" over "make" feel free to contact me in private; such things are part of my standard "repertoire").

vsto - determine a word document if created from blank document or open from an existing document

any expert here got any idea how I can determine a word document if created from blank document or open from an existing document.
I am using Globals.ThisAddIn.Application.ActiveDocument.Saved but it seems not enough.
This should do
if (string.IsNullOrEmpty(WordInstance.ActiveDocument.Path))
{
throw new ApplicationException("Document must be saved first");
}
for vsto developers, please go here
if (Globals.ThisAddIn.Application.ActiveDocument.Path == String.Empty)
{
Word.Dialog dlg;
Object timeout = 3000;
dlg = Globals.ThisAddIn.Application.Dialogs[
Word.WdWordDialog.wdDialogFileSaveAs];
int result = dlg.Display(ref timeout);
}
else
{
Globals.ThisAddIn.Application.ActiveDocument.Save();
}
The result will store which button is pressed (0- cancel, 1- ok, 2- close)