Closed9
Apexを使ってSOQLの結果をCSVに保存する
ゴール
Apexを使ってSOQLの出力結果をCSVファイルに保存する
前提
Playground環境を使用
実行匿名ウィンドウでコードを実行できる状態であること
Apexクラスを作成
作成したApexクラス内に記事のコードをコピー&ペースト
CrearFeedItemCsvBatch
public class CrearFeedItemCsvBatch implements Database.Batchable<sObject>, Database.Stateful {
// *************************************************
// FeedItemを抽出してCSVファイルを作成する
// K.Otsubo 2020/09/26
//
//
// CrearFeedItemCsvBatch bat = new CrearFeedItemCsvBatch();
// ID jobId = Database.executeBatch(bat);
//
// *************************************************
public CrearFeedItemCsvBatch () {
}
public String csvColumnHeader;
public List<String> csvRowValues = new List<String>();
public Database.QueryLocator start(Database.BatchableContext BC){
//ここでParentIdを指定してください
String query = 'select Id,Title, Body,InsertedBy.Name,CreatedDate,ParentId from FeedItem where ParentId=\'005100000095q5sAAA\' ';
return Database.getQueryLocator(query);
}
public void execute(Database.BatchableContext BC, List<sObject> scope){
//Process retrieved SetupAuditTrail records and format field values.
for(FeedItem currFeed : (List<FeedItem>) scope){
//csvColumnHeader = 'Id, Title, Body, Create User Name, LastEditDate , ParentId\n';
String Ids = currFeed.Id != null ? currFeed.Id : '';
String Title = currFeed.Title != null ? String.valueOf(currFeed.Title).escapeCsv() : '';
String Body = currFeed.Body != null ? String.valueOf(currFeed.Body).escapeCsv() : '';
String CreateUser = currFeed.InsertedBy.Name != null ? String.valueOf(currFeed.InsertedBy.Name).escapeCsv() : '';
String formattedDate = currFeed.CreatedDate.format('M/d/yyyy h:mm:ss a z');
String pIds = currFeed.ParentId != null ? currFeed.ParentId : '';
String rowStr = Ids + ',' + Title + ',' + Body + ',' + CreateUser + ','+ formattedDate + ',' + pIds;
csvRowValues.add(rowStr);
}
}
public void finish(Database.BatchableContext BC){
List<Folder> folders = [SELECT Id, Name FROM Folder WHERE Name = 'Sales Tools'];
if(!folders.isEmpty()){
String documentName = 'FeedItem-'+ Datetime.now();
csvColumnHeader = 'Id, Title, Body, Create User Name, CreatedDate , ParentId\n';
String csvFile = csvColumnHeader + String.join(csvRowValues,'\n');
System.debug('******** csvFile=' + csvFile);
Document doc = new Document(Name = documentName, Body = Blob.valueOf(csvFile), FolderId = folders[0].Id, Type = 'csv', ContentType='application/vnd.ms-excel');
insert doc;
}
}
}
匿名実行ウィンドウで実行
CrearFeedItemCsvBatch bat = new CrearFeedItemCsvBatch();
ID jobId = Database.executeBatch(bat);
CSVファイルが生成されているか確認
LightningからClassicに切り替え
コードをそのまま実行しただけでは何も生成されない
List<Folder> folders = [SELECT Id, Name FROM Folder WHERE Name = 'Sales Tools'];
ドキュメントフォルダ「Sales Tools」を新規作成することでCSVファイルが生成された。
生成されたドキュメントの詳細画面
ファイルをExcelで開くと文字化けする
テキストエディタで開くと文字化けしない
生成されるCSVファイルはUTF-8なので、Excelで開くと文字化けする
ただ、csvファイルはUTF-8で作成されていますので
Excelでそのまま開くと日本語が文字化けします。
別途UTF-8が使えるテキストエディタで開いて、文字コードCP-932で保存すれば
Excelで開いても文字化けしなくなります。
ApexでUTF-8からCP-932に変換する方法はあるにはあるのですが、
(正確にはCP-932をUTF-8に変換)
1文字ずつ変換するのでヒープサイズの制限でエラーになりやすいです。
Apexでは制限があるので、実際にはコントローラ(Java Script)内で行っています。
ただし、今回は画面を作らずApexだけなので、文字コード変換は割愛です。
文字コードを変換する場合は下記記事が参考になるかも?
ファイル名に日本語を設定した場合は文字化けしない
String documentName = 'FeedItem_日本語挿入TEST-'+ Datetime.now();
ヘッダーに日本語を設定した場合は文字化けする
csvColumnHeader = 'Id, Title, Body, Create User Name, CreatedDate , ParentId, 日本語挿入TEST, TEST2\n';
カラムに日本語を設定した場合は文字化けする
String rowStr = Ids + ',' + Title + ',' + Body + ',' + CreateUser + ','+ formattedDate + ',' + pIds + ',' + '日本語挿入TEST';
このスクラップは2021/12/14にクローズされました