function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Joseph MurawskiJoseph Murawski 

Problem moving ContentDocument to StaticResource in Lightning Apex code

I use lightning:fileInput to upload a file.  It gets loaded into ContentDocument.  

I need to process the data in the file (excel) so I'm trying to use MetadataService to move it to StaticResource and unzip as talked about in https://andyinthecloud.com/2012/11/04/handling-office-files-and-zip-files-in-apex-part-1/ 
I have the upload working, and when I get the data from contentDocument I can create an attachment that works so I know I'm getting the right data, but when I try creating the staticResource it does not work. 

I'm including the code i am using to do the conversion.  It uses the metadataService talked about in the above listed blog.  I desperately need help figuring out why I am getting url page header data in the blob instead of actually data when the attachment seems to be getting the data.
 
@AuraEnabled
    public static object getFileId(string fName)
    {
        ContentVersion cv = new ContentVersion();
        string fName2 = fName.Replace('.xlsx','');
        ///sfc/servlet.shepherd/version/download/contentversionid
        HttpResponse res = CommonFunctions.getToken();
        String tokenResp = res.getBody();
        String tokenStr = CommonFunctions.parseJSONStatic(tokenResp,'access_token');
        
        cv = [Select Id,contentbodyid,contentdocumentid from ContentVersion Where Title = :fName2 LIMIT 1];
        string hostURL = CommonFunctions.returnHostEnv();  
		//string cURL = hostURL + '/sfc/servlet.shepherd/version/download/' + cv.id;      
		string cURL = hostURL + '/servlet/servlet.FileDownload?file=' + cv.id;
        system.debug('CURL: ' + cURL);
        HTTPResponse resp = new httpResponse();
        HttpRequest reqst = new HttpRequest();
        reqst.setEndpoint(cURL);
        reqst.setMethod('GET');
        reqst.setHeader('Content-Type','application/txt;charset=base64');
        reqst.setHeader('Authorization','Bearer '+tokenStr);  
        reqst.setTimeout(120000);
        Http http1 = new Http();
        resp = http1.send(reqst); 
        blob b = resp.getBodyAsBlob();
        
        /*  Different tests.  None worked
        string strB = b.toString();
        string strC = EncodingUtil.urlEncode(strB, 'utf-8');
        system.debug('XX strFile: ' + strC);
        string strFile = EncodingUtil.urlEncode(resp.getBody(), 'utf-8');
*/
        
        //blob asFile = resp.getBodyAsBlob();
        //string strFile = EncodingUtil.base64Encode(asFile);
        //strFile = EncodingUtil.urlEncode(strFile, 'utf-8');
        //system.debug('XX strFile: ' + strFile);
		//blob asFile2 = blob.valueOf(strFile);      
        
        // At this point we have the file data inside a string
        // Now we need to store it as a resource so it can be unzipped
        // 
        // As a test, try creating an attachment of the file to see what we are actually getting
 		// The following works to grab the file and add into an attachment, so we are getting the correct data from the rest api
        //Attachment oAttachment = new Attachment();
        //oAttachment.parentId = 'a0s36000002wQGMAA2';
        //oAttachment.Body = b;
        //oAttachment.Name = 'TestFile';
        //oAttachment.ContentType = 'application/xlsx';
        //system.debug('XX oAtt.BlobSize: ' + oAttachment.Body.size());
        //insert oAttachment;
        
        MetadataService.MetadataPort service = MetadataService.createService();
        MetadataService.StaticResource staticResource = new MetadataService.StaticResource();
        staticResource.fullName = 'WorkloadPerformanceXLSX';
        //staticResource.contentType = 'application/xlsx';
        staticResource.contentType = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
        //staticResource.contentType = 'application/txt';
        staticResource.cacheControl = 'public';
        // content needs to be a base64 string.
        staticResource.content = b.toString();
        staticResource.description = 'Upload and process workload performance data';
        List<MetadataService.SaveResult> results = service.createMetadata(new MetadataService.Metadata[] { staticResource });
        
        // Process the data here
        //PageReference somefileRef = new PageReference('/resource/folder/' + staticResource.fullName );
		//Blob contentAsBlob = somefileRef.getContent();
		//String contentAsText = contentAsBlob.toString();
        //system.debug('XX XML Content: ' + contentAsText);

        // Clean it up now
        // Delete Static Resource
        //MetadataService.MetadataPort dele_service = MetadataService.createService();
        //List<MetadataService.DeleteResult> dele_results = dele_service.deleteMetadata('StaticResource', new String[] { staticResource.fullName });
        
        // Delete File Content   
        ContentDocument cd = [Select Id from ContentDocument Where id = :cv.contentdocumentid LIMIT 1];
        delete cd;

 
Best Answer chosen by Joseph Murawski
Joseph MurawskiJoseph Murawski
Figured it out.  Instead of doing an api call, I found where the contentversion has a field called VersionData that has the blob.  I just queried it and converted to string and all is good.
 

All Answers

Joseph MurawskiJoseph Murawski
Additional Note:  I started testing again today and noticed that when I create the attachment, there are two files.  The original document and another one that has the same type of information I'm seeing when I view the blob.

How do I get the document information from the contentdocument and not the following?
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <meta HTTP-EQUIV="PRAGMA" CONTENT="NO-CACHE">





<script>
if (this.SfdcApp && this.SfdcApp.projectOneNavigator) { SfdcApp.projectOneNavigator.handleRedirect('https://intelsoftware--RND.cs23.my.salesforce.com?ec=302&startURL=%2Fservlet%2Fservlet.FileDownload%3Ffile%3D06818000000Iom2AAC'); }  else 
if (window.location.replace){ 
window.location.replace('https://intelsoftware--RND.cs23.my.salesforce.com?ec=302&startURL=%2Fservlet%2Fservlet.FileDownload%3Ffile%3D06818000000Iom2AAC');
} else {;
window.location.href ='https://intelsoftware--RND.cs23.my.salesforce.com?ec=302&startURL=%2Fservlet%2Fservlet.FileDownload%3Ffile%3D06818000000Iom2AAC';
} 
</script>

</head>


</html>





<!-- Body events -->
<script type="text/javascript">function bodyOnLoad(){if(window.PreferenceBits){window.PreferenceBits.prototype.csrfToken="null";};}function bodyOnBeforeUnload(){}function bodyOnFocus(){}function bodyOnUnload(){}</script>
			
</body>
</html>


<!--
...................................................................................................
...................................................................................................
...................................................................................................
...................................................................................................
-->

 
Joseph MurawskiJoseph Murawski
OK.  2 files in notes and attachments.  I figured out that what I was seeing as THE file in notes and attachments is really pulling from the ContentDocument area and my test to create an attachment really only created the same attachment info listed above.  So the mystery of how i created an attachment is solved and points back to question of HOW DO I GET THE CONTENTDOCUMENT INFORMATION?

 
Joseph MurawskiJoseph Murawski
Figured it out.  Instead of doing an api call, I found where the contentversion has a field called VersionData that has the blob.  I just queried it and converted to string and all is good.
 
This was selected as the best answer