この記事で学べること
本記事では、Apexクラスを用いてSalesforce上でzipファイルを生成する方法を
紹介します。
投稿の動機
LWC(Lightning Web Components)(html、js)を利用してzipファイルを生成する実装方法は知っていたが、新しくApexクラス上でzipファイルを生成する方法について学んだので、その実装方法を共有したいと思い本投稿を作成しました。
対象
・Apexクラスの実装経験がある程度ある方
・Salesforce上でzipファイルを生成する必要があり、実装方法に困っている方
サンプルコード
例として、取引先レコードに添付されているpdfファイルを一つのzipファイルに圧縮し、それを取引先に添付する実装を記述します。
public void createZipBlob(Id accountId){
// 取引先IDに紐づくContentDocumentLinkをもとにContentVersionを取得
List cvList = [
SELECT PathOnClient
, VersionData
FROM ContentVersion
WHERE ContentDocumentId IN (
SELECT ContentDocumentId
FROM ContentDocumentLink
WHERE LinkedEntityId = :accountId
)
];
// ZipWriterインスタンス生成
Compression.ZipWriter writer = new Compression.ZipWriter();
// zipファイルに格納するファイル情報をZipWriterインスタンスに追加する
for(ContentVersion cv : cvList){
writer.addEntry(cv.PathOnClient, cv.VersionData);
}
// zipファイルをBlob型として取得する
Blob zipAttachment = writer.getArchive();
// 取引先にZipファイルを添付する
ContentVersion newCV = new ContentVersion();
newCV.Title = 'サンプルZIP';
newCV.PathOnClient = 'サンプルZIP.zip';
newCV.VersionData = zipAttachment;
insert newCV;
ContentVersion getCV = [
SELECT ContentDocumentId
FROM ContentVersion
WHERE Id = :newCV.Id
];
ContentDocumentLink newCDL = new ContentDocumentLink();
newCDL.LinkedEntityId = accountId;
newCDL.ContentDocumentId = getCV.ContentDocumentId;
insert newCDL;
}
例をもとにzipファイルを生成する過程についてのみ解説をします。
- ZipWriterインスタンスを生成する
- ファイル情報をZipWriterに追加する
- Blob型としてzipファイルを取得する
手順①:ZipWriterインスタンスの生成
『Compression.ZipWriter writer = new Compression.ZipWriter();』
と記述し、ZipWriterインスタンスを生成する。
ここで定義したZipWriter型変数にzipファイルに格納するファイル情報を
追加していきます。
手順②:ファイル情報の追加
『writer.addEntry(cv.PathOnClient, cv.VersionData);』
と記述することでZipWriter変数にファイル情報を追加することができます。
ここでポイントとしては、addEntryメソッドの引数です。
第一引数には完全パス、第二引数にはBlob情報を記述しています。
今回の例だとContentVersionを使用していますが、
引数に渡す情報が完全パスとBlob情報であればContentVersionを使用しなくても
zipファイルを生成することが可能です。
手順③:zipファイルのBlob情報を取得
『Blob zipAttachment = writer.getArchive();』
と記述することでZipWriter変数からzipファイルの情報をBlob型として取得する
ことが可能です。
※※※ 注意 ※※※
・addEntryメソッドでファイル情報を追加する際、1つのZipWriter変数に重複した
完全パスを追加するとエラーになる
補足
LWC上で対象のファイルをzip化することが可能です。
サンプルとして、本記事ではローカルから選択した複数のファイルをzipに格納し、Apexクラスにzipファイル情報を渡してContentDocumentとして登録する方法を紹介します。
fileUploader.js
import { LightningElement, track } from 'lwc';
import { loadScript } from 'lightning/platformResourceLoader';
import JSZIP from '@salesforce/resourceUrl/jszip';
import uploadZip from '@salesforce/apex/FileZipController.uploadZip';
export default class FileUploader extends LightningElement {
jsZipInitialized = false;
jszip;
@track filesData = [];
connectedCallback() {
if (!this.jsZipInitialized) {
loadScript(this, JSZIP).then(() => {
this.jszip = new window.JSZip();
this.jsZipInitialized = true;
});
}
}
handleFileChange(event) {
if (event.target.files.length > 0) {
[...event.target.files].forEach(file => {
let reader = new FileReader();
reader.onload = () => {
let base64 = reader.result.split(',')[1];
this.filesData.push({
fileName: file.name,
base64: base64
});
};
reader.readAsDataURL(file);
});
}
}
async handleUpload() {
if (this.filesData.length === 0) {
alert('ファイルを選択してください');
return;
}
let zip = new window.JSZip();
this.filesData.forEach(f => {
zip.file(f.fileName, f.base64, { base64: true });
});
const zipBlob = await zip.generateAsync({ type: 'blob' });
// Blob → Base64変換
const reader = new FileReader();
reader.onload = async () => {
const zipBase64 = reader.result.split(',')[1];
try {
await uploadZip({
fileName: 'merged.zip',
base64Data: zipBase64
});
alert('ZIPファイルをSalesforceに保存しました');
} catch (err) {
console.error(err);
}
};
reader.readAsDataURL(zipBlob);
}
}
fileUploader.html
<template>
<lightning-card title="ZIPファイル作成 (LWC)">
<lightning-input type="file" multiple onchange={handleFileChange}></lightning-input>
<lightning-button label="ZIP化してSalesforceに保存" onclick={handleUpload}></lightning-button>
</lightning-card>
</template>
FileZipController.cls
public with sharing class FileZipController {
@AuraEnabled
public static Id uploadZip(String fileName, String base64Data) {
Blob fileBlob = EncodingUtil.base64Decode(base64Data);
ContentVersion cv = new ContentVersion();
cv.Title = fileName;
cv.PathOnClient = fileName;
cv.VersionData = fileBlob;
insert cv;
return cv.Id;
}
}
最後に
ここまで見ていただきありがとうございます。
今回の投稿をあげるきっかけになったのは、業務上の案件で顧客からSalesforce上で
zipファイルを生成したいというご要望をいただき、実際に実装してみて面白いなと
思ったので投稿しました。
これからも実務で役立つ実装方法を紹介していきたいと思いますので、
別の投稿も見ていただけたら嬉しいです!


















































