Tuesday, May 11, 2010

Create a print feature without creating custom ASPX pages

Hi all,

For one of the projects I had create a print feature where users could easily print the list items in document library. SharePoint 2007 does not provide this functionality OOTB. I have seen similar features on codeplex project where Ishai Sagi has created an aspx page and a corresponding master page. But I did not like this idea for creating an additional page for this functionality. I have developed a simpler technique without using any kind of ASPX pages. 

Ingredients: 
--A custom document library 
--IE developer
--A javascript file 
--A CSS file 

The Recipe

Step1: Create a custom list schema. You can follow my previous posts. 

Step2: Create a simple feature with element files. We write a custom action in the elements xml file so that users can go to "Action" menu and click on the "Print List" item: 

elementsPrint.xml
........................................................................................
<?xml version="1.0" encoding="utf-8" ?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <CustomAction
    Id="fcef3254-f1a0-419c-bda9-4be18a18cc5d"
    Title="Print List"
    Description="A printer-friendly view of the list."
    RegistrationId="List"
    Location="Microsoft.SharePoint.StandardMenu"
    GroupId="ActionsMenu"
    ImageUrl="_layouts/images/Print/Print.gif">
    <UrlAction Url="javascript:PrintPreview(this);"  />
  </CustomAction>
 </Elements>
.....................................................................................
Note that we have defined a JavaScript function named PrintPreview which we will define in next step.  

Step3: The JavaScript file:
A PrintPreview funtion could be easily found on any ASP.NET site. On of these scripts could be found here. Basically, when we user click on "Print List" at the SharePoint, we can utilize the browser to show the print preview. Number 7 defines the print preview. Therefore, we can get rid of the ASPX pages. 

print.js 
--------------------------------------------------------------
//Function used by the Printmenu Feature.
function  PrintPreview(Object)
{
    SystemPrintPreview(7);
}

//Function used by the Printmenu Feature.
function SystemPrintPreview(OLECMDID)
{
 //var OLECMDID = 10;
 /* OLECMDID values:
 * 6 - print
 * 7 - print preview
 * 8 - page setup (for printing)
 * 1 - open window
 * 4 - Save As
 * 10 - properties
 */try
 {
 var PROMPT = 1; // 1 PROMPT & 2 DONT PROMPT USER
 var oWebBrowser = document.getElementById("WebBrowser1");
 if(oWebBrowser == null)
 {
 var sWebBrowser = '<OBJECT ID="WebBrowser1" WIDTH=0 HEIGHT=0 CLASSID="CLSID:8856F961-340A-11D0-A96B-00C04FD705A2"></OBJECT>';
 document.body.insertAdjacentHTML('beforeEnd', sWebBrowser);
 oWebBrowser = document.getElementById("WebBrowser1");
 //WebBrowser1.outerHTML = "";
  }
oWebBrowser.ExecWB(OLECMDID,PROMPT);
}
catch(e){alert("Printing failed! " + e.message);}
---------------------------------------------------------------


Step4: The CSS file.
Apparently, when you try to print preview of the page, there are some unnecessary items such as breadcrumb, title, left navaigation menu etc. We can use IE developer and identify the "TD" and "TABLE" to hide those elements. 

print.css
----------------------------------------------------------------------------
@media print
{

        BODY {color: silver; background: black;}
    P {
        FONT-SIZE: 25px; COLOR: #000; LINE-HEIGHT: 15px; FONT-FAMILY: Verdana, Arial, Helvetica, sans-serif
    }
    TD {
        FONT-SIZE: 25px; COLOR: #000; LINE-HEIGHT: 15px; FONT-FAMILY: Verdana, Arial, Helvetica, sans-serif
    }
    TH {
        FONT-SIZE: 25px; COLOR: #000; LINE-HEIGHT: 15px; FONT-FAMILY: Verdana, Arial, Helvetica, sans-serif
    }
    LI {
        FONT-SIZE: 25px; COLOR: #000; LINE-HEIGHT: 15px; FONT-FAMILY: Verdana, Arial, Helvetica, sans-serif
    }
    INPUT {
        FONT-SIZE: 25px; COLOR: #000; LINE-HEIGHT: 15px; FONT-FAMILY: Verdana, Arial, Helvetica, sans-serif
    }
    TEXTAREA {
        FONT-SIZE: 25px; COLOR: #000; LINE-HEIGHT: 15px; FONT-FAMILY: Verdana, Arial, Helvetica, sans-serif
    }
    SELECT {
        FONT-SIZE: 25px; COLOR: #000; LINE-HEIGHT: 15px; FONT-FAMILY: Verdana, Arial, Helvetica, sans-serif
    }
       
table.ms-menutoolbar
    {
        display:none;
    }
   
    td.ms-titlearea
    {
        display:none;
    }
   
    td.ms-sitetitle
    {
        display:none;
    }
   
}
---------------------------------------------------------------------------------------------------

Step5: Inject external JavaScript and files into SharePoint. 

We know that "AllItems.aspx" will show the print menu. Therefore, we can register the external  JavaScript and CSS files onto the "AllItems.aspx" page. Two lines of code will do our work.

We can register the files under PlaceHolderAdditionalPageHead ID: 
----------------------------------------------------------
<asp:content contentplaceholderid="PlaceHolderAdditionalPageHead" runat="server">
    <SharePoint:RssLink runat="server" />
   
    <!-- Register the Print.js -->
    <SharePoint:ScriptLink ID="ScriptLink1" Name="/PrintList/Print.js" runat="server" Localizable="false">
    </SharePoint:ScriptLink>
   
    <!-- Register the Print css -->
    <SharePoint:CssRegistration  ID="ScriptLink2" Name="/_layouts/PrintList/styles/Print.css" runat="server">
    </SharePoint:CssRegistration>
   
</asp:content>
-------------------------------------------------------

Note: 

1) JavaScript File:
on the first line (javascript file), you may get an error if you specify the path as  Name="/_layouts/PrintList/Print.js"

BUG
Microsoft.SharePoint.SPException: Cannot make a cache safe URL for "/_layouts/PrintList/print.js", file not found. Please verify that the file exists under the layouts directory.

But if we specify the path as Name="/PrintList/Print.js", it will work fine. 

2) CSS file: 
There is no issue with CSS file though.

I hope it will help others.

Cheers, 
--aaroh 

Download the JavaScript, CSS, elementPrint.xml and AllItems.aspx here.

No comments:

How to display Sharegate administrative dynamic reports via Power BI on SharePoint Online

After working in the SharePoint domain for a couple of years as SharePoint consultant , I am fortunate enough to help customers from man...