I’m using SharePoint 2010 and InfoPath 2010 on IE 11, w/Windows 7 operating system.
I have an InfoPath form that I want the user to be able to fill in the data and have the option to download a copy (with the data), as a pdf or word document – save as feature.
I see in InfoPath filler (office 2010) I can perform this “save as PDF” function but not in SharePoint 2010. Is there a setting I’m missing or do I have to go the route of extending SharePoint foundation w/ASP.net?
Thanks
Sorry, there is no native SharePoint 2010 functionality that meets your requirements. But there are several 3rd party tools you can purchase, or, of course, follow your own suggestion and pursue custom options.
I created a shim for SP2010 that will cause all Infopath forms in a sharepoint 2010 site to download, as long as the link to the form is in Sharepoint 2010. You will need jquery 1.12 for this to run.
$(function() {
if (document.getElementsByTagName('BODY')[0].innerHTML.indexOf('.xsn') != -1) {
$('a[href$=".xsn"]').each(function(index) {
var self = $(this);
var fileLocation = '';
var spDownloadsUrl = '/_layouts/download.aspx?SourceUrl=';
//GRAB LINK'S HREF LINK PATH AND URI ENCODE IT
var currentUrl = encodeURI(self.attr('href'));
//IF THE HREF IS TO A NETWORK FILE LOCATION EXIT THE PROCESS AND LEAVE IT ALONE
if (currentUrl.indexOf('file:') != -1) {
return;
}
//SHAREPOINT 2010 DOC LIST ELEMENTS HAVE INLINE JS ALTERING THE LINK BEHAVIOR, SO THEY NEED TO BE REMOVED
self.removeAttr('onclick');
self.removeAttr('onmousedown');
self.removeAttr('onfocus');
//IF THE LINK'S URL IS ABSOLUTE PATH, BUILD IT AS RELATIVE
if (currentUrl.indexOf('.com') != -1) {
var urlSplitOnDotCom = currentUrl.split('.com');
var urlAfterDotCom = urlSplitOnDotCom[1];
var urlPartsArr = urlAfterDotCom.split('/');
//REBUILD URL FROM ARRAY
var newPathname = "";
for (i = 1; i < urlPartsArr.length; i++) {
newPathname += "/";
newPathname += urlPartsArr[i];
}
fileLocation = newPathname;
} else {
fileLocation = currentUrl;
}
//ADD NEW URL TO INFOPATH FILE'S HREF ATTRIBUTE
self.attr('href', spDownloadsUrl + fileLocation);
});
}
});
Related
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.
We have a column that contains links to PDFs that starts on line 4 (e.g B4:B). I am trying to find a way to automatically download the PDF files that are accessed via the links to a folder on Drive. This is what I have so far:
function savePDFs() {
var sheet = SpreadsheetApp.getActiveSheet();
var data = sheet.getDataRange().getValues();
for (var i = 3; i < data.length; i++) {
Logger.log(data[i][1]);
}
}
Presumably the above code would write the links starting in column B (index value of [1]) on row 4 (i value of 3) (ie., B4) until the bottom of the data set (eg., data.length()).
I'm now confused about how to access and save the PDF link that are written in the logger to a folder.
Would someone be willing to help me out? I'm currently having to go to each link, click Save Link As... and then navigate to the folder that I'd like to save the linked PDF to. My hope is to modify the above process using code.
Update: I found this bit of code here that may help me out. Note, I changed the PDF link to a currently valid PDF link.
var urlOfThePdf = 'http://download.p4c.philips.com/l4b/9/929000277411_eu/929000277411_eu_pss_aenaa.pdf';// an example of online pdf file
var folderName = 'GAS';// an example of folder name
function saveInDriveFolder(){
var folder = DocsList.getFolder(folderName);// get the folder
var file = UrlFetchApp.fetch(urlOfThePdf); // get the file content as blob
folder.createFile(file);//create the file directly in the folder
}
Okay, I'm going to go and noodle with the data that is in the logger to confirm that the data is in properly formatted PDF links, then I'm going to test this new bit of code out. I feel like I'm getting close.
You can't force a download of a file from an apps script, you must try that from an HTMLService and not sure it will work.
For your need I would recommend to create a dedicated folder and you add all the pdf in it and you use the download function of the drive interface to download all files in one clic.
In drive, a file can be put in several folders so the pdf files stay in the original folder but you create a new folder 'PDF for download" for example and you put them in it. To do that from drive interface you have to click on "shift"+Z when file(s) is/are selected.
For you current list of file you just have to add in your loop the add to folder function. You can use this function.
function addFileToFolder(id){
var folderPDF = DriveApp.getFolderById("Id OFFolder to put pdf");
var file = DriveApp.getFileById(id);
folderPDF.addFile(file);
}
EDIT : Function will browse list of url, get the file and make a copy in a dedicated folder on the user drive.
function downloadInDriveFolder(){
var folderID = 'Id of the folder';// put id of the folder
var folder = DriveApp.getFolderById(folderID)// get the folder
var sheet = SpreadsheetApp.getActiveSheet();
var data = sheet.getDataRange().getValues();
for (var i = 3; i < data.length; i++) {
var blob = UrlFetchApp.fetch(data[i][1]).getContent();
var pdf = DriveApp.createFile(blob);
pdf.setName(data[i][0]);//Put as name of the file the value in col A
folder.addFile(pdf);
}
}
Well I figured it out. I was expecting more code, but this does it for me:
function listPDFs() {
var out = new Array();
var row = 3; //row index of 0 = row 1
var column = 4; // column index of 0 = column A
var sheet = SpreadsheetApp.getActiveSheet();
var data = sheet.getDataRange().getValues();
var folder = DriveApp.getFolderById("this is where you paste your folder id"); // destination folder (this is the 0978SDFSDFKJHSDF078Y98hkyo looking value when you right click your folder and select "Get Link")
for (var i=row ; i<data.length ; i++) {
if(data[i][column] !== "") {
var file = UrlFetchApp.fetch(data[i][column]);
folder.createFile(file);
}
}
return
}
As you can see, I included a row and column variable so that I could easily change these.
I haven't figured out how to assemble them into a merged PDF, but I did figure out that I could sort them by date (which places the top most item first) and then right click and select "Open With...PDF Mergy", which then moves the PDFs into PDF Mergy and merges them up in the correct order. You can find PDF Mergy in the Chrome App Store. If I figure out how to automatically call PDF Mergy from GAS, I'll post that up--but for the time being the above code has saved us a ton of time...so I'm calling it good enough for the time being.
I have a simple form and body field. when user upload an attachment I want to remove any attachment already in the body field of the document. how can I do this in my save button.
I have tried to set the properites on the fileUpload control to always change the filename to tha same name but this does not replace the file, instead it adds a new file and add a new sequential number to it
<xp:fileUpload id="fileUpload1" value="#{userdoc.Body}" filename="profile" seUploadname="false"></xp:fileUpload>
I have also tried to loop all embedded attachments in body field before before save, and all attachments are then removed, but my new attachment is not added.
A little late, but in case anyone gets here just as I did through Google...
There's also another option: a NotesXSPDocument.getAttachmentList("rtitem") returns a list of attachments in the document. Each entry is of type DominoDocument.AttachmentValueHolder which has a getState() property that returns if a file was already in the document or just added. To remove the file that was already in the document you could add this SSJS code to a save button (assuming "files" is the name of the richtext item holding the files):
var attList = docFile.getAttachmentList("files");
for(var i=0; i<attList.size(); i++) {
var att = attList.get(i);
if (att.getState()==0) { //STATE_INDOCUMENT: this is the 'old' file: remove it
docFile.removeAttachment("files", att.getName() );
} else if (att.getState()==1) { //STATE_ADDED: this is the new file
//leave it
}
}
This can be done by removing all attachments first (use the removeAllAttachments function from NotesXSPDocument object) and then attach the uploaded file manually to the richtext item.
This SSJS code has to be added to beforeRenderResponse-event of your XPage / Custom Control:
var con = facesContext.getExternalContext();
var request:com.sun.faces.context.MyHttpServletRequestWrapper = con.getRequest();
var map:java.util.Map = request.getParameterMap();
var fileDataName = getClientId('fileUpload1') ;
var fileData:com.ibm.xsp.http.UploadedFile = map.get( fileDataName );
if( fileData == null ){
return;
}
var tempFile:java.io.File = fileData.getServerFile();
var correctedFile = new java.io.File( tempFile.getParentFile().getAbsolutePath() +
java.io.File.separator + fileData.getClientFileName() );
var success = tempFile.renameTo(correctedFile);
try{
document1.removeAllAttachments("Body");
}catch(e){}
var rtFiles:NotesRichTextItem = null;
if(!(document1.getDocument().hasItem("Body"))){
rtFiles = document1.getDocument().createRichTextItem("Body")
}else{
rtFiles = document1.getDocument().getFirstItem("Body");
}
rtFiles.embedObject(lotus.domino.local.EmbeddedObject.EMBED_ATTACHMENT, "",
correctedFile.getAbsolutePath(), null);
correctedFile.renameTo(tempFile);
document1.save();
The richtext item where the files are stored is "Body", the name of the datasource is "document1". The Fileupload control is "fileUpload1".
There are two limitations:
You cannot use this with a save button, you have to use a normal button / link which makes a full refresh (see what Serdar Basegmez wrote above)
You have to refresh the page after a upload once again, otherwise you will not see the uploaded file in a file download conrol (maybe a partial refresh to this control may work).
EDIT:
Sorry, my fault: You can use this code above in a submit button that saves the document. Then you don't have to refresh the page manually!
How might I create a SharePoint 2010 content query web part programatically and add it to a SharePoint page?
The post Adding/Removing web part in SharePoint website programmatically using C# code contains a detailed description of adding and removing Web Parts.
Here's a snippet taken from the above post adding a Web Part to a page (replace the WebPartToBeAdded pseudoclass with ContentByQueryWebPart):
using (SPSite spSiteTest = new SPSite(“SiteURL”)
{
using (SPWeb spWebTest = spSiteTest.OpenWeb())
{
SPWebPartCollection webparts = spWebTest.GetWebPartCollection("WebPageURL",Storage.Shared);
//create new webpart object
WebPartToBeAdded wpNew = new WebPartToBeAdded();
//set properties of new webpart object
wpNew.ZoneID = "WebPartZoneIDWhereWebPartIsToBeAdded";
wpNew.Title = "Web Part Title";
wpNew.ChromeState = System.Web.UI.WebControls.WebParts.PartChromeState.Normal;
wpNew.ChromeType = System.Web.UI.WebControls.WebParts.PartChromeType.None;
//add new webpart object to webparts collection
webparts.Add(wpNew);
//update spWeb object
spWebTest.Update();
}
}
I have to create a SharePoint 2010 ribbon element (tabs, buttons, groups, etc.). Is there a way to create such elements via the SharePoint API without using custom actions?
Edit:
I've just found the possibilty to add elements like this (link):
SPRibbon r = SPRibbon.GetCurrent(Page);
r.RegisterDataExtension(/* XmlNode containing ribbon element code */);
Another workaround would be to append a custom web control and append dynamic controls to this "placeholder".
Is there a way to create elements without using xml nodes?
For layouts pages and webparts, you can create Ribbon without any XML, using Ribbon Utils for SharePoint 2010.
For example, for layouts page, you will need to inherit from RibbonUtils.RibbonLayoutsPage and provide your definition of a ribbon.
Code for the most simple page with custom ribbon tab & one button on it will look like this:
public partial class MyRibbonPage : RibbonLayoutsPage
{
public override TabDefinition GetTabDefinition()
{
return new TabDefinition()
{
Id = "TestRibbon",
Title = "Test",
Groups = new GroupDefinition[]
{
new GroupDefinition()
{
Id = "TestGroup",
Title = "Test group",
Template = GroupTemplateLibrary.SimpleTemplate,
Controls = new ControlDefinition[]
{
new ButtonDefinition()
{
Id = "TestButton",
Title = "Test button",
CommandJavaScript = "alert('test!');",
Image32Url = "/_layouts/images/lg_ICHLP.gif",
}
}
}
}
};
}
}
You will find more examples and very good documentation on the project page on CodePlex.
AFAIK, it is for now most simple and quick way to create ribbon programmatically for application pages & webparts.