ken_nogi/pleasanter/develop/総務 【β】売却・相続)名義変更一覧/02_帳票スクリプト.js
Kenichiro NOGI 48d993652f 20251006
2025-10-06 09:23:38 +09:00

325 lines
10 KiB
JavaScript

$p.ex.createReportData = async function (reportName, reportGuid) {
//共通キー項目
const keys = [
'ResultId',
'SiteId',
'ItemTitle',
'Title',
'Body',
'Status',
'Manager',
'Owner',
'Locked',
'Comments',
'Creator',
'CreatedTime',
'Updator',
'UpdatedTime',
'Ver'
]
let recordId = $p.id();
//レコードデータを取得
const record = await $p.ex.getRecordData(recordId);
let param = {}
let recordData = [];
//共通キー項目のデータをセット
for (let key of keys) {
param[key] = record[key];
}
console.log('Record Data:', record);
//ClassHashの値をセット
const sortedClassKeys = Object.keys(record.ClassHash).sort();
sortedClassKeys.forEach(function (key) {
param[key] = record.ClassHash[key];
});
//Numhashの値をセット
const sortedNumKeys = Object.keys(record.NumHash).sort();
sortedNumKeys.forEach(function (key) {
param[key] = record.NumHash[key];
});
//DateHashの値をセット
const sortedDateKeys = Object.keys(record.DateHash).sort();
sortedDateKeys.forEach(function (key) {
if (record.DateHash[key] != '1899-12-30T00:00:00') {
param[key] = dateFormatChange(record.DateHash[key]);
}
});
//DescriptionHashの値をセット
const sortedDescKeys = Object.keys(record.DescriptionHash).sort();
sortedDescKeys.forEach(function (key) {
let data = record.DescriptionHash[key];
//複数の改行を1つにまとめる
if (typeof data === 'string') {
data = data.replace(/(\r?\n){2,}/g, '\n');
}
param[key] = data;
});
//CheckHashの値をセット
const sortedCheckKeys = Object.keys(record.CheckHash).sort();
sortedCheckKeys.forEach(function (key) {
param[key] = record.CheckHash[key];
});
//日付変換
param.CreatedTime = dateFormatChange(param.CreatedTime);
param.UpdatedTime = dateFormatChange(param.UpdatedTime);
//ユーザーコード変換
param.Creator = userList[param.Creator] ? userList[param.Creator].name : param.Creator;
param.Updator = userList[param.Updator] ? userList[param.Updator].name : param.Updator;
param.Manager = userList[param.Manager] ? userList[param.Manager].name : param.Manager;
param.Owner = userList[param.Owner] ? userList[param.Owner].name : param.Owner;
param['OutputUser'] = userList[$p.userId()] ? userList[$p.userId()].name : "";
recordData.push(param);
createReport(reportName, reportGuid, recordData);
}
async function createReport(reportName, reportGuid, recordData = [], templateType = 'xlsx') {
// ウインドウ全体にモーダルを表示
if ($('#global-modal').length === 0) {
const modalHtml = `
<div id="global-modal" style="
position: fixed;
z-index: 9999;
top: 0; left: 0; right: 0; bottom: 0;
background: rgba(0,0,0,0.5);
display: flex;
align-items: center;
justify-content: center;
">
<div style="
background: #fff;
padding: 40px 60px;
border-radius: 8px;
font-size: 1.2em;
box-shadow: 0 2px 16px rgba(0,0,0,0.2);
text-align: center;
">
処理中です。しばらくお待ちください...
</div>
</div>
`;
$('body').append(modalHtml);
}
const templateName = reportName;
const templateGuid = reportGuid;
//Guidを使ってバイナリデータを取得
const templateFile = await $p.ex.getTemplateFile(templateGuid);
const templateBinary = await base64ToArrayBuffer(templateFile.Base64);
//XlsPopulate Workbookを作成
let workbook = await XlsxPopulate.fromDataAsync(templateBinary);
//paramシート取得
let param = workbook.sheet('param');
//param.cells().value('');
if (!param) {
console.error('paramシートが見つかりません');
return;
}
//レコードデータを取得
for (let record of recordData) {
console.log('Processing record:', record);
let row = 1;
for (const key of Object.keys(record)) {
param.cell(row, 1).value(key);
param.cell(row, 2).value(record[key]);
row++;
}
}
const xlsxblob = await workbook.outputAsync();
const base64data = await blobToBase64(xlsxblob);
//年月日時分秒の文字列を生成
const now = new Date();
const dateStr = now.getFullYear() + ('0' + (now.getMonth() + 1)).slice(-2) + ('0' + now.getDate()).slice(-2) +
'_' + ('0' + now.getHours()).slice(-2) + ('0' + now.getMinutes()).slice(-2) + ('0' + now.getSeconds()).slice(-2);
let downloadFileName = templateName + '■' + dateStr + '.' + templateFile.Extension;
//PDF変換APIを呼び出す
/*
sendExcelAndSavePdf(base64data, downloadFileName)
.then(pdfBlob => {
// PDF Blobをダウンロード
saveAs(pdfBlob, downloadFileName.replace(/\.(xlsx|docx|pptx)$/, 'pdf'));
});
*/
if (templateType === 'xlsx') {
//Blobをダウンロード
saveAs(xlsxblob, downloadFileName);
} else if (templateType === 'pdf') {
//PDF出力
sendExcelAndSavePdf(base64data, downloadFileName)
.then(pdfBlob => {
// PDF Blobをダウンロード
saveAs(pdfBlob, downloadFileName.replace(/\.(xlsx|docx|pptx)$/, 'pdf'));
});
}
console.log('帳票出力が完了しました:', downloadFileName);
$('#global-modal').remove();
}
//blobデータからbase64データを変換する関数
function blobToBase64(blob) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onloadend = () => resolve(reader.result.split(',')[1]);
reader.onerror = reject;
reader.readAsDataURL(blob);
});
}
//A列からキーを検索し、該当する行の指定した列に値をセットする関数
function setValueToSheet(sheet, col, key, value) {
//左端の列を下まで走査する
const lastRow = 1;//sheet.usedRange().endCell('down').rowNumber();
for (let row = 1; row <= lastRow; row++) {
const keyCell = sheet.cell(row, 1);
const keyValue = keyCell.value();
if (!keyValue) continue;
if (keyValue === key) {
sheet.cell(row, col).value(value);
break;
}
}
return sheet;
}
//base64エンコードされたバイナリデータをArrayBufferに変換
async function base64ToArrayBuffer(base64) {
const binaryString = atob(base64);
const len = binaryString.length;
const bytes = new Uint8Array(len);
for (let i = 0; i < len; i++) {
bytes[i] = binaryString.charCodeAt(i);
}
return bytes.buffer;
}
//プリザンターから1件のレコードデータを取得する関数
$p.ex.getRecordData = async function (id) {
//もしidが空鳴らんなら、空のオブジェクトを返す
if (!id) {
return {};
}
//プリザンターへゲット処理
const url = 'https://' + location.hostname + '/pleasanter/api/items/' + id + '/get'
const json = {
'ApiVersion': 1.1,
'ApiKey': apiKey,
}
const res = await fetch(url, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(json)
});
const resData = await res.json();
//console.log(resData);
return resData.Response.Data[0];
}
//プリザンターから1件の添付ファイルのbase64データを取得する関数
$p.ex.getTemplateFile = async function (guid) {
//もしidが空鳴らんなら、空のオブジェクトを返す
if (!guid) {
return {};
}
//プリザンターへゲット処理
const url = 'https://' + location.hostname + '/pleasanter/api/binaries/' + guid + '/get'
const json = {
'ApiVersion': 1.1,
'ApiKey': apiKey,
}
const res = await fetch(url, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(json)
});
const resData = await res.json();
//console.log(resData);
return resData.Response;
}
//日付フォーマット変換関数
function dateFormatChange(dateStr) {
let dateObj = new Date(dateStr);
//時分秒が00:00:00の場合は日付のみを返す
if (dateObj.getHours() === 0 && dateObj.getMinutes() === 0 && dateObj.getSeconds() === 0) {
//YYYY/MM/DD形式で返す
return dateObj.toLocaleDateString('ja-JP'); //日本語のロケールで日付をフォーマット
} else {
//YYYY/MM/DD HH:mm:ss形式で返す
return dateObj.toLocaleString('ja-JP', { timeZone: 'Asia/Tokyo' }); //日本語のロケールで日付と時間をフォーマット
}
}
//ExcelからPDFに変換するスクリプト
// 送信先サーバーのURLとAPIキー
const SERVER_URL = 'https://neo999.next-hd.net:30309/pdfConvert'; // サーバーのURLに合わせて変更
const API_KEY = 'pgqhLFWbDFu4Byz#4afNYX2F6Fa1&$KPjved$8%sUdTQV52caip#EpIKxYUkdd4S'; // サーバーと同じAPIキー
// base64とfileNameを引数で受け取り、変換後のPDFを自動ダウンロード
async function sendExcelAndSavePdf(base64, fileName) {
try {
const response = await fetch(SERVER_URL, {
method: 'POST',
body: JSON.stringify({ base64, fileName }),
headers: {
'Content-Type': 'application/json',
'x-api-key': API_KEY
}
// agent: new https.Agent({ rejectUnauthorized: false }) // ブラウザでは不要
});
if (!response.ok) {
throw new Error(`サーバーエラー: ${response.status} ${response.statusText}`);
}
// PDFバイナリを取得
const pdfBlob = await response.blob();
return pdfBlob;
} catch (err) {
console.error('変換エラー:', err.message);
}
}