325 lines
10 KiB
JavaScript
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);
|
|
}
|
|
} |