-
Notifications
You must be signed in to change notification settings - Fork 356
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
New Command- Convert-PnPFileToPdf (#3435)
* Feature 3422- New Commandlet- Convert-PnPFileToPdf * Rename to have filename match the cmdlet name and some minor cleanup * Added changelog entry * Resolving comments by Gautam Sheth --------- Co-authored-by: Koen Zomers <[email protected]> Co-authored-by: Gautam Sheth <[email protected]>
- Loading branch information
1 parent
90c618a
commit bcdd552
Showing
4 changed files
with
333 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,151 @@ | ||
--- | ||
Module Name: PnP.PowerShell | ||
schema: 2.0.0 | ||
applicable: SharePoint Online | ||
online version: https://pnp.github.io/powershell/cmdlets/Convert-PnPFileToPDF.html | ||
external help file: PnP.PowerShell.dll-Help.xml | ||
title: Convert-PnPFileToPDF | ||
--- | ||
|
||
# Convert-PnPFileToPDF | ||
|
||
## SYNOPSIS | ||
Converts a file to Pdf | ||
|
||
## SYNTAX | ||
|
||
|
||
### Save to local path | ||
```powershell | ||
Convert-PnPFileToPDF -Url <String> -Path <String> [-Force] | ||
``` | ||
|
||
### Return as memorystream | ||
```powershell | ||
Convert-PnPFileToPDF -Url <String> -AsMemoryStream | ||
``` | ||
|
||
### Save to SharePoint Online (Same SiteCollection) | ||
```powershell | ||
Convert-PnPFileToPDF -Url <String> -Folder <String> | ||
``` | ||
|
||
## DESCRIPTION | ||
Allows converting of a file from SharePoint Online. The file contents can either be directly saved to local disk, or stored in memory for further processing, or Can be uploaded back to SharePoint Online SiteCollection | ||
|
||
## EXAMPLES | ||
|
||
### EXAMPLE 1 | ||
```powershell | ||
Convert-PnPFileToPDF -Url "/sites/project/Shared Documents/Document.docx" -AsMemoryStream | ||
``` | ||
|
||
Retrieves the file and converts to PDF, and outputs its content to the console as a Memory Stream | ||
|
||
### EXAMPLE 2 | ||
```powershell | ||
Convert-PnPFileToPDF -Url "/sites/project/Shared Documents/Document.docx" | ||
``` | ||
|
||
Retrieves the file and converts to PDF, and outputs its content to the console as a Memory Stream | ||
|
||
### EXAMPLE 3 | ||
```powershell | ||
Convert-PnPFileToPDF -Url "/sites/project/Shared Documents/Document.docx" -Path "C:\Temp" | ||
``` | ||
|
||
Retrieves the file and converts to PDF, and save it to the given local path | ||
|
||
### EXAMPLE 4 | ||
```powershell | ||
Convert-PnPFileToPDF -Url "/sites/project/Shared Documents/Document.docx" -Path "C:\Temp" -Force | ||
``` | ||
|
||
Retrieves the file and converts to PDF, and save it to the given local path. Force parameter will override the existing file in the location where the document gets saved. | ||
|
||
### EXAMPLE 5 | ||
```powershell | ||
Convert-PnPFileToPDF -Url "/sites/SampleTeamSite/Shared Documents/Nishkalank's/Book.xlsx.docx" -Folder "Archive" | ||
``` | ||
|
||
Retrieves the file and converts to PDF, and save it to the given Document library (Folder) in SharePoint Online (Same SiteCollection). Returns the saved file information in the console. | ||
|
||
|
||
|
||
## PARAMETERS | ||
|
||
### -Url | ||
The URL (server or site relative) to the file | ||
|
||
```yaml | ||
Type: String | ||
Parameter Sets: (All) | ||
Aliases: ServerRelativeUrl, SiteRelativeUrl | ||
|
||
Required: True | ||
Position: 0 | ||
Default value: None | ||
Accept pipeline input: True (ByValue) | ||
Accept wildcard characters: False | ||
``` | ||
### -AsMemoryStream | ||
```yaml | ||
Type: SwitchParameter | ||
Parameter Sets: Return as memorystream | ||
|
||
Required: True | ||
Position: Named | ||
Default value: None | ||
Accept pipeline input: False | ||
Accept wildcard characters: False | ||
``` | ||
### -Path | ||
Local path where the file should be saved | ||
```yaml | ||
Type: String | ||
Parameter Sets: Save to local path | ||
|
||
Required: False | ||
Position: Named | ||
Default value: None | ||
Accept pipeline input: False | ||
Accept wildcard characters: False | ||
``` | ||
### -Force | ||
Overwrites the file if it exists. | ||
```yaml | ||
Type: SwitchParameter | ||
Parameter Sets: Save to local path | ||
|
||
Required: False | ||
Position: Named | ||
Default value: None | ||
Accept pipeline input: False | ||
Accept wildcard characters: False | ||
``` | ||
### -Folder | ||
The destination library in the site | ||
```yaml | ||
Type: FolderPipeBind | ||
Parameter Sets: (UPLOADTOSHAREPOINT) | ||
|
||
Required: True | ||
Position: Named | ||
Default value: None | ||
Accept pipeline input: False | ||
Accept wildcard characters: False | ||
``` | ||
## RELATED LINKS | ||
[Microsoft 365 Patterns and Practices](https://aka.ms/m365pnp) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,153 @@ | ||
using Microsoft.SharePoint.Client; | ||
using PnP.Framework.Utilities; | ||
using System.Management.Automation; | ||
using PnP.PowerShell.Commands.Base; | ||
using PnP.PowerShell.Commands.Utilities.REST; | ||
using System.IO; | ||
using PnP.PowerShell.Commands.Base.PipeBinds; | ||
|
||
namespace PnP.PowerShell.Commands.Files | ||
{ | ||
[Cmdlet(VerbsData.Convert, "PnPFileToPDF")] | ||
public class ConvertFileToPDF : PnPWebCmdlet | ||
{ | ||
private const string URLTOPATH = "Save to local path"; | ||
private const string URLASMEMORYSTREAM = "Return as memorystream"; | ||
private const string UPLOADTOSHAREPOINT = "Upload to SharePoint"; | ||
|
||
[Parameter(Mandatory = true, ParameterSetName = URLTOPATH, Position = 0, ValueFromPipeline = true)] | ||
[Parameter(Mandatory = true, ParameterSetName = URLASMEMORYSTREAM, Position = 0, ValueFromPipeline = true)] | ||
[Parameter(Mandatory = true, ParameterSetName = UPLOADTOSHAREPOINT, Position = 0, ValueFromPipeline = true)] | ||
[Alias("ServerRelativeUrl", "SiteRelativeUrl")] | ||
public string Url; | ||
|
||
[Parameter(Mandatory = true, ParameterSetName = URLTOPATH)] | ||
public string Path = string.Empty; | ||
|
||
[Parameter(Mandatory = false, ParameterSetName = URLTOPATH)] | ||
public SwitchParameter Force; | ||
|
||
[Parameter(Mandatory = true, ParameterSetName = UPLOADTOSHAREPOINT)] | ||
[ValidateNotNullOrEmpty] | ||
public FolderPipeBind Folder; | ||
|
||
[Parameter(Mandatory = false, ParameterSetName = URLASMEMORYSTREAM)] | ||
public SwitchParameter AsMemoryStream; | ||
|
||
protected override void ExecuteCmdlet() | ||
{ | ||
if (string.IsNullOrEmpty(Path)) | ||
{ | ||
Path = SessionState.Path.CurrentFileSystemLocation.Path; | ||
} | ||
else if (!System.IO.Path.IsPathRooted(Path)) | ||
{ | ||
Path = System.IO.Path.Combine(SessionState.Path.CurrentFileSystemLocation.Path, Path); | ||
} | ||
|
||
Url = Utilities.UrlUtilities.UrlDecode(Url.Replace("+", "%2B")); | ||
var serverRelativeUrl = GetServerRelativeUrl(Url); | ||
var fileObj = GetFileByServerRelativePath(serverRelativeUrl); | ||
var sourceFileName = fileObj.Name.ToString().Substring(0, fileObj.Name.ToString().LastIndexOf(".")); | ||
var apiUrl = GeneratePdfApiUrl(Url, sourceFileName, fileObj); | ||
byte[] response = RestHelper.GetByteArrayAsync(Connection.HttpClient, apiUrl, GraphAccessToken).GetAwaiter().GetResult(); | ||
var fileToDownloadName = !string.IsNullOrEmpty(sourceFileName) ? sourceFileName : "Download"; | ||
|
||
switch (ParameterSetName) | ||
{ | ||
case URLTOPATH: | ||
var fileOut = System.IO.Path.Combine(Path, $"{fileToDownloadName}.pdf"); | ||
if (!Directory.Exists(Path)) | ||
{ | ||
throw new PSArgumentException("Path does not exists"); | ||
} | ||
if (!Force && System.IO.File.Exists(fileOut)) | ||
{ | ||
WriteWarning($"File '{fileToDownloadName}' exists already. Use the -Force parameter to overwrite the file."); | ||
} | ||
else | ||
{ | ||
System.IO.File.WriteAllBytes(fileOut, response); | ||
WriteObject($"File saved as {fileOut}"); | ||
} | ||
break; | ||
|
||
case URLASMEMORYSTREAM: | ||
var stream = new MemoryStream(response); | ||
WriteObject(stream); | ||
break; | ||
|
||
case UPLOADTOSHAREPOINT: | ||
var targetLibrary = EnsureFolder(); | ||
Stream fileStream = new MemoryStream(response); | ||
var targetFileName = $"{fileToDownloadName}.pdf"; | ||
var uploadedFile = targetLibrary.UploadFileAsync(targetFileName, fileStream, true).GetAwaiter().GetResult(); | ||
ClientContext.Load(uploadedFile); | ||
try | ||
{ | ||
ClientContext.ExecuteQueryRetry(); | ||
} | ||
catch (ServerException) | ||
{ | ||
ClientContext.Load(uploadedFile, f => f.Length, f => f.Name, f => f.TimeCreated, f => f.TimeLastModified, f => f.Title); | ||
ClientContext.ExecuteQueryRetry(); | ||
} | ||
WriteObject(uploadedFile); | ||
break; | ||
} | ||
} | ||
|
||
private string GetServerRelativeUrl(string url) | ||
{ | ||
var webUrl = CurrentWeb.EnsureProperty(w => w.ServerRelativeUrl); | ||
return url.ToLower().StartsWith(webUrl.ToLower()) ? url : UrlUtility.Combine(webUrl, Url); | ||
} | ||
|
||
private Microsoft.SharePoint.Client.File GetFileByServerRelativePath(string serverRelativeUrl) | ||
{ | ||
var fileListItem = CurrentWeb.GetFileByServerRelativePath(ResourcePath.FromDecodedUrl(serverRelativeUrl)); | ||
ClientContext.Load(fileListItem, f => f.Exists, f => f.ListItemAllFields, f => f.ListId, f => f.Name); | ||
ClientContext.ExecuteQueryRetry(); | ||
if (fileListItem.Exists) | ||
{ | ||
return fileListItem; | ||
} | ||
else | ||
{ | ||
throw new PSArgumentException($"No file found with the provided Url {serverRelativeUrl}", "Url"); | ||
} | ||
} | ||
|
||
private string GeneratePdfApiUrl(string url, string sourceFileName, Microsoft.SharePoint.Client.File fileObj) | ||
{ | ||
var siteId = PnPContext.Site.Id.ToString(); | ||
var listId = fileObj.ListId.ToString(); | ||
var itemId = fileObj.ListItemAllFields.Id.ToString(); | ||
return $"https://{Connection.GraphEndPoint}/v1.0/sites/{siteId}/lists/{listId}/items/{itemId}/driveItem/content?format=pdf"; | ||
} | ||
|
||
|
||
private Folder EnsureFolder() | ||
{ | ||
// First try to get the folder if it exists already. This avoids an Access Denied exception if the current user doesn't have Full Control access at Web level | ||
CurrentWeb.EnsureProperty(w => w.ServerRelativeUrl); | ||
|
||
Folder library = null; | ||
try | ||
{ | ||
library = Folder.GetFolder(CurrentWeb); | ||
library.EnsureProperties(f => f.ServerRelativeUrl); | ||
return library; | ||
} | ||
// Exception will be thrown if the library does not exist yet on SharePoint | ||
catch (ServerException serverEx) when (serverEx.ServerErrorCode == -2147024894) | ||
{ | ||
// create the library | ||
CurrentWeb.CreateList(ListTemplateType.DocumentLibrary, Folder.ServerRelativeUrl, false, true, "", false, false); | ||
library = Folder.GetFolder(CurrentWeb); | ||
library.EnsureProperties(f => f.ServerRelativeUrl); | ||
return library; | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters