엑셀 채점결과 행열 변환 및 채점기준표와 문항 수 동일하게 조정
This commit is contained in:
163
psdExport_2.js
163
psdExport_2.js
@@ -12,9 +12,9 @@ const getToday = require('./getToday.js');
|
||||
const todayDate = getToday();
|
||||
|
||||
// --------------------------------------------------------
|
||||
// const scoringJson = require('./DIC_2503A.json');
|
||||
const scoringJson = require('./DIC_2503A.json');
|
||||
// const scoringJson = require('./DIC_2503B.json');
|
||||
const scoringJson = require('./DIC_2503C.json');
|
||||
// const scoringJson = require('./DIC_2503C.json');
|
||||
// const scoringJson = require('./DIC_2503D.json');
|
||||
|
||||
// TEST
|
||||
@@ -23,7 +23,7 @@ const scoringJson = require('./DIC_2503C.json');
|
||||
// const scoringJson = require('./DIC_2503C_TEST.json');
|
||||
// const scoringJson = require('./DIC_2503D_TEST.json');
|
||||
// --------------------------------------------------------
|
||||
// const answerFilesDir = './output/A/DIC';
|
||||
const answerFilesDir = './output/A/DIC';
|
||||
// const answerFilesDir = './output/B/DIC';
|
||||
// const answerFilesDir = './output/C/DIC';
|
||||
// const answerFilesDir = './output/D/DIC';
|
||||
@@ -31,19 +31,19 @@ const scoringJson = require('./DIC_2503C.json');
|
||||
// TEST
|
||||
// const answerFilesDir = './output/A/TEST';
|
||||
// const answerFilesDir = './output/B/TEST';
|
||||
const answerFilesDir = './output/C/TEST';
|
||||
// const answerFilesDir = './output/C/TEST';
|
||||
// const answerFilesDir = './output/D/TEST';
|
||||
|
||||
// --------------------------------------------------------
|
||||
// const outputExcelFile = './'+todayDate+'_DIC_2503A_채점결과.xlsx';
|
||||
const outputExcelFile = './'+todayDate+'_DIC_2503A_채점결과.xlsx';
|
||||
// const outputExcelFile = './'+todayDate+'_DIC_2503B_채점결과.xlsx';
|
||||
// const outputExcelFile = './' + todayDate + '_DIC_2503C_채점결과.xlsx';
|
||||
// const outputExcelFile = './'+todayDate+'_DIC_2503C_채점결과.xlsx';
|
||||
// const outputExcelFile = './'+todayDate+'_DIC_2503D_채점결과.xlsx';
|
||||
|
||||
// TEST
|
||||
// const outputExcelFile = './'+todayDate+'_DIC_2503A_TEST.xlsx';
|
||||
// const outputExcelFile = './'+todayDate+'_DIC_2503B_TEST.xlsx';
|
||||
const outputExcelFile = './'+todayDate+'_DIC_2503C_TEST.xlsx';
|
||||
// const outputExcelFile = './'+todayDate+'_DIC_2503C_TEST.xlsx';
|
||||
// const outputExcelFile = './'+todayDate+'_DIC_2503D_TEST.xlsx';
|
||||
// --------------------------------------------------------
|
||||
|
||||
@@ -118,51 +118,117 @@ studentDirs.forEach(student => {
|
||||
scoringResultList.push(scoringResult);
|
||||
});
|
||||
|
||||
// Flatten the resultData for better representation in Excel
|
||||
const flattenedData = scoringResultList.map(student => {
|
||||
const name = student["0"];
|
||||
const flattened = { "학생": student["0"] };
|
||||
// // Flatten the resultData for better representation in Excel
|
||||
// const flattenedData = scoringResultList.map(student => {
|
||||
// // const name = student["0"];
|
||||
// const flattened = { "학생": student["0"] };
|
||||
|
||||
// excel에 표시하지 않을 key값들
|
||||
const exceptKeys = [
|
||||
"0", // 학생 이름 항상 제외
|
||||
"1", // psd1
|
||||
"2", // psd2
|
||||
]
|
||||
const exceptSubkeys = [
|
||||
"videoStartTime",
|
||||
"openingStartTime",
|
||||
];
|
||||
Object.keys(student).forEach(key => {
|
||||
if (exceptKeys.includes(key)) {
|
||||
return;
|
||||
}
|
||||
Object.keys(student[key]).forEach(subKey => {
|
||||
if (exceptSubkeys.includes(subKey)) {
|
||||
return;
|
||||
// // excel에 표시하지 않을 key값들
|
||||
// const exceptKeys = [
|
||||
// "0", // 학생 이름 항상 제외
|
||||
// // "1", // psd1
|
||||
// // "2", // psd2
|
||||
// ]
|
||||
// const exceptSubkeys = [
|
||||
// "videoStartTime",
|
||||
// "openingStartTime",
|
||||
// ];
|
||||
// Object.keys(student).forEach(key => {
|
||||
// if (exceptKeys.includes(key)) {
|
||||
// return;
|
||||
// }
|
||||
// Object.keys(student[key]).forEach(subKey => {
|
||||
// if (exceptSubkeys.includes(subKey)) {
|
||||
// return;
|
||||
// }
|
||||
// flattened[`${key}-${subKey}`] = student[key][subKey];
|
||||
// });
|
||||
// });
|
||||
// return flattened;
|
||||
// });
|
||||
|
||||
/**
|
||||
* scoringResultList 배열을 엑셀에 출력하기 위한 데이터 정리 함수
|
||||
* @param {Array} scoringResultList - 학생별 채점 결과 리스트
|
||||
* @returns {Array} - 엑셀에 출력할 데이터 배열
|
||||
*/
|
||||
function prepareExcelData(scoringResultList) {
|
||||
return scoringResultList.map(student => {
|
||||
const flattened = { "학생": student["0"] }; // 학생 이름을 첫 번째 열로 설정
|
||||
|
||||
// 제외할 키와 서브키 정의
|
||||
const exceptKeys = [
|
||||
"0", // 학생 이름 제외
|
||||
// "1", // psd1
|
||||
// "2", // psd2
|
||||
];
|
||||
const exceptSubkeys = ["videoStartTime", "openingStartTime"]; // 제외할 서브키
|
||||
|
||||
// 학생 데이터 순회
|
||||
Object.keys(student).forEach(key => {
|
||||
if (exceptKeys.includes(key)) {
|
||||
return; // 제외할 키는 건너뜀
|
||||
}
|
||||
|
||||
// 서브키 순회
|
||||
if (typeof student[key] === "object") {
|
||||
Object.keys(student[key]).forEach(subKey => {
|
||||
if (exceptSubkeys.includes(subKey)) {
|
||||
return; // 제외할 서브키는 건너뜀
|
||||
}
|
||||
flattened[`${key}-${subKey}`] = student[key][subKey];
|
||||
});
|
||||
} else {
|
||||
// 서브키가 없는 경우
|
||||
flattened[key] = student[key];
|
||||
}
|
||||
flattened[`${key}_${subKey}`] = student[key][subKey];
|
||||
});
|
||||
|
||||
return flattened;
|
||||
});
|
||||
return flattened;
|
||||
});
|
||||
}
|
||||
// console.log(flattenedData);
|
||||
const flattenedData = prepareExcelData(scoringResultList);
|
||||
|
||||
function transposeData(data) {
|
||||
// 데이터가 없으면 빈 배열 반환
|
||||
if (data.length === 0) return [];
|
||||
|
||||
// 첫 번째 객체의 키(열 제목) 가져오기
|
||||
const keys = Object.keys(data[0]);
|
||||
|
||||
// 행과 열을 변환
|
||||
const transposed = keys.map(key => {
|
||||
const row = { "항목": key }; // 각 열 제목을 "항목"으로 설정
|
||||
data.forEach((item, index) => {
|
||||
//console.log(data[index]['학생']);
|
||||
row[data[index]['학생']] = item[key]; // 각 학생의 데이터를 열로 추가
|
||||
});
|
||||
return row;
|
||||
});
|
||||
|
||||
return transposed;
|
||||
}
|
||||
|
||||
// const transposedData = transposeData(flattenedData);
|
||||
const transposedData = transposeData(flattenedData).slice(1);
|
||||
|
||||
// 엑셀 파일 생성
|
||||
const worksheet = XLSX.utils.json_to_sheet(flattenedData);
|
||||
// const worksheet = XLSX.utils.json_to_sheet(flattenedData);
|
||||
const worksheet = XLSX.utils.json_to_sheet(transposedData);
|
||||
const workbook = XLSX.utils.book_new();
|
||||
|
||||
// 열 너비 계산
|
||||
const columnWidths = Object.keys(flattenedData[0]).map(key => {
|
||||
const maxLength = Math.max(
|
||||
key.length, // 열 제목의 길이
|
||||
...flattenedData.map(row => (row[key] ? row[key].toString().length : 0)) // 각 셀의 데이터 길이
|
||||
);
|
||||
return { wch: maxLength + 1 }; // 여유 공간 추가
|
||||
});
|
||||
// const columnWidths = Object.keys(flattenedData[0]).map(key => {
|
||||
// const maxLength = Math.max(
|
||||
// key.length, // 열 제목의 길이
|
||||
// ...flattenedData.map(row => (row[key] ? row[key].toString().length : 0)) // 각 셀의 데이터 길이
|
||||
// );
|
||||
// return { wch: maxLength + 1 }; // 여유 공간 추가
|
||||
// });
|
||||
|
||||
// 열 너비 설정
|
||||
worksheet['!cols'] = columnWidths;
|
||||
// worksheet['!cols'] = columnWidths;
|
||||
// Add the worksheet to the workbook
|
||||
XLSX.utils.book_append_sheet(workbook, worksheet, '채점 결과');
|
||||
|
||||
@@ -246,8 +312,7 @@ function getGmepScore(gmepData, scoringJson, index) {
|
||||
// const subtitleOrder = type === 'video' ? 2 : type === 'opening' ? 1 : null;
|
||||
// 2503회 문제오류 처리를 위한 임시 변경
|
||||
const subtitleOrder = (type === 'video' || type === 'videoIsExist') ? 2 : (type === 'opening' ? 1 : null);
|
||||
const startTime = type === 'video' ? videoStartTime
|
||||
: type === 'opening' ? openingStartTime : null;
|
||||
const startTime = type === 'video' ? videoStartTime : type === 'opening' ? openingStartTime : null;
|
||||
|
||||
[ele, ele2, ele3] = [ele, ele2, ele3].map(e => e?.replace(/{subtitleIndex}/g, subtitleIndex));
|
||||
[ele, ele2, ele3] = [ele, ele2, ele3].map(e => e?.replace(/{subtitleOrder}/g, subtitleOrder));
|
||||
@@ -478,20 +543,12 @@ function getGmepScore(gmepData, scoringJson, index) {
|
||||
}
|
||||
}
|
||||
|
||||
/* 현재 문제점 ****************************************************
|
||||
* ele2 xpath구문을 수행했을때
|
||||
* /CROwneUnit[position() = //CRTrackList/CRTrackClip[sum(preceding-sibling::CRTrackClip/@Length) = 170]/@ClipIndex + 1]/CRCUnitArr/@Name
|
||||
* position() = //CRTrackList/CRTrackClip[sum(preceding-sibling::CRTrackClip/@Length) = 170 부분에서
|
||||
* 시작시간이 170이 아닌 경우 false값이 반환되고 0으로 인식되어
|
||||
* //CROwneUnit[0]/CRCUnitArr/@Name 의 값이 반환됨
|
||||
****************************************************************/
|
||||
|
||||
// 문제의 타입이 video(동영상자막) 또는 opening(오프닝자막)일 경우
|
||||
else if (type == "video" || type == "opening") {
|
||||
const trackClipNode = getTrackClipNode(gmepXmlDoc, type, videoStartTime, openingStartTime);
|
||||
|
||||
// 찾으려는 자막이 존재하지 않는 경우
|
||||
// (2-28) 문항의 경우 오프닝 자막이 없어도 xpath구문의 sum함수 결과값이 0이 반환되는것을 방지
|
||||
if ( trackClipNode === undefined ) {
|
||||
if ( trackClipNode === undefined && clipIndex === null ) {
|
||||
scoringResult[key] = 0;
|
||||
continue;
|
||||
}
|
||||
@@ -678,8 +735,8 @@ function getScore(psdData, scoring, index) {
|
||||
// value: "Arial"
|
||||
// result: ["Arial-BoldItalicMT"]
|
||||
else if (type == "font") {
|
||||
// console.log(`result ${result}`);
|
||||
const font = result[0].split('-')[0];
|
||||
// console.log(`result ${result}`);
|
||||
// console.log(`font: ${font}`);
|
||||
scoringResult[key] = result.length > 0 && value === font ? point : 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user