Closed9

Apexを使ってSOQLの結果をCSVに保存する

miyakonmiyakon
miyakonmiyakon

作成したApexクラス内に記事のコードをコピー&ペースト
https://qiita.com/Keiji_otsubo/items/767ed7fbbf2f72943a14

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に切り替え

コードをそのまま実行しただけでは何も生成されない

miyakonmiyakon
List<Folder> folders = [SELECT Id, Name FROM Folder WHERE Name = 'Sales Tools'];

ドキュメントフォルダ「Sales Tools」を新規作成することでCSVファイルが生成された。


生成されたドキュメントの詳細画面

ファイルをExcelで開くと文字化けする

テキストエディタで開くと文字化けしない

miyakonmiyakon

生成されるCSVファイルはUTF-8なので、Excelで開くと文字化けする

miyakonmiyakon

ただ、csvファイルはUTF-8で作成されていますので
Excelでそのまま開くと日本語が文字化けします。
別途UTF-8が使えるテキストエディタで開いて、文字コードCP-932で保存すれば
Excelで開いても文字化けしなくなります。

ApexでUTF-8からCP-932に変換する方法はあるにはあるのですが、
(正確にはCP-932をUTF-8に変換)
1文字ずつ変換するのでヒープサイズの制限でエラーになりやすいです。
Apexでは制限があるので、実際にはコントローラ(Java Script)内で行っています。
ただし、今回は画面を作らずApexだけなので、文字コード変換は割愛です。

https://qiita.com/Keiji_otsubo/items/767ed7fbbf2f72943a14

miyakonmiyakon

ファイル名に日本語を設定した場合は文字化けしない

 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にクローズされました