Menu Bar

Friday 31 August 2012

Uploading a Document using Visualforce and a Custom Controller


Problem

Sometimes you may want to create a process where uploading a document is mandatory. You can create a single Visualforce page with all of the fields for the record plus the field required to upload a document. You could also develop a wizard interface that allows the user to walk through a series of steps in which one would be to upload a document.

Solution

Create a Visualforce page that references a controller (documented below). Note the enctype attribute on the <apex:form> tag. This Visualforce page uses only the fields necessary for uploading a document but can be expanded to include field for other records or documents in the process.
01<apex:page controller="FileUploadController">

02  <apex:sectionHeader title="Visualforce Example" subtitle="File Upload Example"/>

03  

04  <apex:form enctype="multipart/form-data">

05    <apex:pageMessages />

06    <apex:pageBlock title="Upload a File">

07  

08      <apex:pageBlockButtons >

09        <apex:commandButton action="{!upload}" value="Save"/>

10      </apex:pageBlockButtons>

11  

12      <apex:pageBlockSection showHeader="false" columns="2" id="block1">

13  

14        <apex:pageBlockSectionItem >

15          <apex:outputLabel value="File Name" for="fileName"/>

16          <apex:inputText value="{!document.name}" id="fileName"/>

17        </apex:pageBlockSectionItem>

18  

19        <apex:pageBlockSectionItem >

20          <apex:outputLabel value="File" for="file"/>

21          <apex:inputFile value="{!document.body}" filename="{!document.name}" id="file"/>

22        </apex:pageBlockSectionItem>

23  

24        <apex:pageBlockSectionItem >

25          <apex:outputLabel value="Description" for="description"/>

26          <apex:inputTextarea value="{!document.description}" id="description"/>

27        </apex:pageBlockSectionItem>

28  

29        <apex:pageBlockSectionItem >

30          <apex:outputLabel value="Keywords" for="keywords"/>

31          <apex:inputText value="{!document.keywords}" id="keywords"/>

32        </apex:pageBlockSectionItem>

33  

34      </apex:pageBlockSection>

35  

36    </apex:pageBlock>

37  </apex:form>

38</apex:page>

Create an Apex class that behaves as the controller in the Visualforce page. The upload() method is key.
view source
print?
01public with sharing class FileUploadController {

02  

03  public Document document {

04    get {

05      if (document == null)

06        document = new Document();

07      return document;

08    }

09    set;

10  }

11  

12  public PageReference upload() {

13  

14    document.AuthorId = UserInfo.getUserId();

15    document.FolderId = UserInfo.getUserId(); // put it in running user's folder

16  

17    try {

18      insert document;

19    } catch (DMLException e) {

20      ApexPages.addMessage(new ApexPages.message(ApexPages.severity.ERROR,'Error uploading file'));

21      return null;

22    } finally {

23      document.body = null; // clears the viewstate

24      document = new Document();

25    }

26  

27    ApexPages.addMessage(new ApexPages.message(ApexPages.severity.INFO,'File uploaded successfully'));

28    return null;

29  }

30  

31}

Discussion

Visualforce takes care of all the hard work by updating the document from the file that's uploaded. All your controller class needs to do is store it. If you would like to attach the document to a specific record you will need to use the Attachment object instead of the Document object.

Notes

Make sure you take a look at the finally block in the controller code above. The finally block always executes when the try block exits regardless if an error occurs or not. You need to ensure you clear out document’s body (document.body = null) so that the blob is not automatically included in the serialized image of the controller. If you do not clear out the body, you’ll get the following view state error: "Maximum view state size limit (128K) exceeded. Actual viewstate size for this page was…"

3 comments:

Anonymous said...

I sure wish you had written a Unit Test for this example. My email address is DMail805@Gmail.com if you happen to have one that you can send to me. I have written an Apex Class controller that is called with the Click of a button on a Visualforce page. The only thing it does really is upload a .csv the file, store and display the data. But I haven't been able to figure out how to write a Unit Test for this yet. I think an Unit Test for this example would help me.

LG G7 Price said...

LG G7 pouch cases are genuinely handy covers that provide both security and comfort to your device. Check Out LG G7 Features.

Maridev said...

Smart move for your career is Choosing to do Oracle Course in Chennai at Infycle!! Do you know why this name is chosen for Infycle. Infycle where the place we offered Infinity of Oracle.
Yes!!! But not only Oracle, More than 20+ courses are offered here 5000+ students are placed in top MNC’s Company with good salary packages. For admission 7502633633.