I have received a query on how to get all attachments from all items in a SharePoint List. We can achieve this from different ways,

  • Accessing the attachments folder from the SharePoint List using SharePoint Designer or
  • Mapping the attachments folder to File Share.
  • Access the attachment folder of the list based on the path using program
  • Get the attachments of each list items in a List using a program

Here, we are going to follow the last method for accessing the attachments in a list using PnP JavaScript library and render that in SharePoint Framework webpart.

First of all create a SharePoint Framework webpart project using the Yeoman generator with the following command

yo @microsoft/sharepoint

Generate the project with No JavaScript option, because I am going to show the example without any JavaScript framework. So that, you can use the snippet any JavaScript framework on creating the webpart.

After the creation of the project, add the pnp js library dependencies by running the following npm commmand

npm install –save @pnp/common @pnp/sp @pnp/logging @pnp/odata

To access the item and attachments object using pnp js library, add the following import statements to the webpart ts file.

import { sp, Item } from "@pnp/sp";

If we want to download or upload the attachment files from webpart, we have to include the following import statement below the sp import statement.

import { AttachmentFile, AttachmentFiles, AttachmentFileInfo } from '@pnp/sp/src/attachmentfiles';

To show the attachments from all list items in a webpart, add the below methods under the _WebPart class within _webpart.ts file.

//Retrieve all the attachments from all items in a SharePoint List
  private getSPData(): void {
    let attachmentfiles: string = "";

    sp.web.lists.getByTitle("My List").items
    .select("Id,Title,Attachments,AttachmentFiles")
    .expand("AttachmentFiles")
    .filter('Attachments eq 1')
    .get().then((response: Item[]) => {
    
      response.forEach((listItem: any) => {
        listItem.AttachmentFiles.forEach((afile: any) => {
          attachmentfiles += `<li>(${listItem.Id}) ${listItem.Title} - ${afile.FileName}</li>`;
        });

      });    
      attachmentfiles = `<ul>${attachmentfiles}</ul>`;;
      this.renderData(attachmentfiles);
    });
  }
private renderData(strResponse: string): void {
  const htmlElement = this.domElement.querySelector("#pnpinfo");
  htmlElement.innerHTML = strResponse;
}

getSPData() method gets the attachment files from all items from the list “My List“. Add the “Attachments eq 1” to the filter to retrieve the items, which contains attachments. Use the expand method to get the attachment files of the list items in a single request.
In the response, we are generating the html as a list of attachment files with the associated Item Id and Title.
renderData() method adds the generated html to the webpart.

Replace the render() method with the below code snippet. This used to call the getSPData() and update the retrieved values within the element pnpinfo.

public render(): void {
  this.domElement.innerHTML = `
    <div class="${ styles.pnPDemos}">
      <div class="${ styles.container}">
        <div class="${ styles.row}">
          <div class="${ styles.column}">
            <div id="pnpinfo"></div>
          </div>
        </div>
      </div>
    </div>`;
  this.getSPData();
}

After running the webpart in the SharePoint page, it will display the Item id, title and attachments. It will be nice to have download link in the attachment file.

attachmentfiles += `<li>(${listItem.Id}) ${listItem.Title} - ${afile.FileName}</li>`;

Replace the above line with the following code snippet. Then the webpart renders the download link to each attachment file.

  let downloadUrl = this.context.pageContext.web.absoluteUrl + "/_layouts/download.aspx?sourceurl=" + afile.ServerRelativeUrl;
  attachmentfiles += `<li>(${listItem.Id}) ${listItem.Title} - <a href='${downloadUrl}'>${afile.FileName}</a></li>`;

And the output looks like below,


Leave a Reply

Your email address will not be published. Required fields are marked *