Files replaced Attachments in Salesforce. Now any type of document upload becomes part of Files/Content in Salesforce. With all the other advantages over Attachments, the best one is Files can be shared across objects, means having a attachment with multiple parents.
In lightning experience, any attachment upload is uploaded as files after Winter 16. But in salesforce classic you need to go to files settings and check “Files uploaded to the Attachments related list on records are uploaded as Salesforce Files, not as attachments” to make this happen. From then onwards Attachments will be uploaded as Files from classic too.
We all being uploading attachment in different ways one and of the ways is via Apex. Now how to upload Files as Attachment using Apex ? It is very simple you just need to understand the object relations and thats it.
ContentDocument
This object record you don’t create. It gets created when you create Content Version who is child of ContentDocument. But Id of this record will be required to do other stuff.
ContentVersion
This is where you attachment goes, you need to create this record in same way as you used to do for attachments
String yourFiles = 'Lets assume this is your binary string of the files'; ContentVersion conVer = new ContentVersion(); conVer.ContentLocation = 'S'; // S specify this document is in SF, use E for external files conVer.PathOnClient = 'ionicLogo.png'; // The files name, extension is very important here which will help the file in preview. conVer.Title = 'Proposal '; // Display name of the files conVer.VersionData = EncodingUtil.base64Decode(yourFiles); // converting your binary string to Blog insert conVer;
This will insert your files but it will still not be visible under Attachment/Files related list. For that you need to create
ContentDocumentLink
This will share the files with users, records, groups etc. You can create multiple records to attach the same files under multiple records
// First get the content document Id from ContentVersion Id conDoc = [SELECT ContentDocumentId FROM ContentVersion WHERE Id =:conVer.Id].ContentDocumentId; //Create ContentDocumentLink ContentDocumentLink cDe = new ContentDocumentLink(); cDe.ContentDocumentId = conDoc; cDe.LinkedEntityId = yourObjectRecord.Id; // you can use objectId,GroupId etc cDe.ShareType = 'I'; // Inferred permission, checkout description of ContentDocumentLink object for more details cDe.Visibility = 'InternalUsers'; insert cDe;
This will create files under your object records.
How can you update a file with a new version through Apex?
LikeLike
Just create a new content version with same content document Id
LikeLike
So I want files to be converted to attachments, but I’m having a bit of trouble setting this up. Would this be an Apex Class or Apex Trigger? If it’s a trigger, would I need to create code for every object in Salesforce? Is this what the code should look like?
String yourFiles = ‘Lets assume this is your binary string of the files’; (what should go here?)
ContentVersion conVer = new ContentVersion();
conVer.ContentLocation = ‘S’; // S specify this document is in SF, use E for external files
conVer.PathOnClient = ‘ionicLogo.png’; // The files name, extension is very important here which will help the file in preview.
conVer.Title = ‘Proposal ‘; // Display name of the files
conVer.VersionData = EncodingUtil.base64Decode(yourFiles); // converting your binary string to Blog
insert conVer;
// First get the content document Id from ContentVersion
Id conDoc = [SELECT ContentDocumentId FROM ContentVersion WHERE Id =:conVer.Id].ContentDocumentId;
//Create ContentDocumentLink
ContentDocumentLink cDe = new ContentDocumentLink();
cDe.ContentDocumentId = conDoc;
cDe.LinkedEntityId = yourObjectRecord.Id; // you can use objectId,GroupId etc
cDe.ShareType = ‘I’; // Inferred permission, checkout description of ContentDocumentLink object for more details
cDe.Visibility = ‘InternalUsers’;
insert cDe;
LikeLike
Attachment is separate object, you different code
LikeLike
Hi, can we attach the file and doc into the Notes and attachment object as a related list of the Custom Object? By using this block of code.
LikeLike
Could you please help to bulkify the code as I am trying to insert attachment via Batch and then converting to Content Version and CDL
LikeLike
Please try below code:
Note :for file preview from record to get working we need to fetch ContentDocumentId from ContentVersion object.Pass single or list of ContentDocumentId with and sObject id and check in the Object record.
Public static void insertAttachments(List docIDs,String caseId){ System.debug(‘docId=apexcls’+docIDs); List contentDocumentLinks = new List();
ContentDocumentLink contentDocumentLink=new ContentDocumentLink(); try{ List contentVersionsLst=[select id ,ContentDocumentId from ContentVersion where ContentDocumentId IN: docIDs] ;
if(contentVersionsLst.size()!=null){ for(ContentVersion contentVersion : contentVersionsLst){ contentDocumentLink = createContentDocumentLink(contentVersion.ContentDocumentId,caseId);
contentDocumentLinks.add(contentDocumentLink); } } insert contentDocumentLinks;
} catch(Exception e) { System.debug(LoggingLevel.ERROR,’####ERROR:’+e.getMessage()); } }
LikeLike
Hi Vivek, thank you for your blog post. I believe it may get me closer to what I am trying to do. If you could comment on feasibility of it, I’d appreciate. The short version of it is, I have an Apex controller that shares data with an lwc. The Apex controller gets its data from a REST API, which is capable of sending the content of image files as encoded strings. I’d like to receive the image data in the Apex controller, write it to a file, and then send a link to the file to the lwc so that in can be included in an image tag, e.g. . Does all of this sound doable to you, and what other aspects fo APex development/SF would I need to become familiar with? Thank you!
LikeLike
Yes, it is doable. Just insert the file and when you query the file again or if you have the ids you can create the link and send it to lwc as string. Just query already existing link and try to replace the ids.
LikeLike
Hi,
I’m trying to upload an image from mobile app built using iOS mobile sdk taking your doc as reference. In your document while creating ContentVersion you’re making use of String yourFiles = “”. What is that exactly? Is that my image converted to a binary string? If so again we are decoding that at conVer.VersionData = EncodingUtil.base64Decode(yourFiles) right? Can you elaborate more on these 2 lines once?
LikeLike
Yes files are base64 encoded string. If you get already a base64 encoded string then you don’t need to convert
LikeLike
Hi
I am using
Blob yourFiles = Blob.valueOf(‘All your info goes here monday’);
ContentVersion conVer = new ContentVersion();
conVer.ContentLocation = ‘S’;
conVer.PathOnClient = ‘test’+’.’+’pdf’;
conVer.Title = ‘Proposal1Monday14’;
conVer.VersionData = EncodingUtil.base64Decode(s);
conVer.origin = ‘H’;
insert conVer;
Id conDoc = [SELECT FileExtension ,ContentDocumentId FROM ContentVersion WHERE Id =:conVer.Id].ContentDocumentId;
ContentVersion cv =
[SELECT Title, FileExtension, VersionData, ContentDocumentId,
ContentLocation, FileType
FROM ContentVersion
WHERE ContentDocumentId = :conDoc
AND IsLatest = true];
//Create ContentDocumentLink
ContentDocumentLink cDe = new ContentDocumentLink();
cDe.ContentDocumentId = conDoc;
cDe.LinkedEntityId = ‘XXXXXXXXX’;
cDe.ShareType = ‘I’;
cDe.Visibility = ‘InternalUsers’;
insert cDe;
The above snippet does create a PDF type attachment. But does not give a preview. And even when I download and try to open the file using a Online viewer – it says Error loading File.
LikeLike
Hi vivek,
My requirement is, i want to upload a file that file (.doc) is fixed format i want to update it and download it with sfdc. is it possible?
LikeLike
Hi, I have my image being inserted through apex as a File object as shown above however my inserted record (which is a .png image) doesn’t contain the image seems the URL is a little wrong any help would be greatly appreciated
LikeLike
Hi Moe,
I think the problem will be in your files VersionData, if it is formatted wrong through whatever service you are uploading then the image won’t render correctly
LikeLiked by 1 person
I want to validate the file format of the file uploaded on file related list on record detail page and on the object record feed. Which content object to use to achieve this. Contentversion, contentdocument or contentdocumentlink.please help me on this.
LikeLike
Hi Sukruti,
It depends on how you are uploading the document. If from Lightning component you can restrict certain type by adding validation on JavaScript
LikeLike
I want to validate the file format of the file uploaded on file related list on record detail page and on the object record feed. Which content object to use to achieve this. Contentversion, contentdocument or contentdocumentlink. Please help on this.
LikeLike
You are awesome. Thank you very much for such a nice document. Really helpful
LikeLike
Good article.
pardon me if i am wrong, I have one question. In this article, you are only written for creating files not the conversation of files to attachments.
LikeLike
Hi, do you know how to add a new version of ContentDocument using apex?
LikeLike
Hi I have a question about this. I understood how we add files and document link through apex. I’m trying to create a file with VF page rendered as PDF, file is created but file type is coming as unknown any idea how to resolve this.
cv.VersionData = pr.getContentAsPDF();
LikeLike
As I mentioned in the code PathOnClient field should have proper extensions YourFileName.pdf then it will take the proper file type
LikeLike