Spaces:
Running
Running
import * as XLSX from "xlsx"; | |
import { ExcelColumnsName } from "../constants"; | |
// Функция для разделения текста на документы | |
const splitDocuments = (text: string) => { | |
const regex = /Документ: \[\d+\]/g; | |
const matches = text.match(regex); | |
if (!matches) return [text]; | |
const documents = []; | |
let lastIndex = 0; | |
matches.forEach((match, index) => { | |
const startIndex = text.indexOf(match, lastIndex); | |
if (index > 0) { | |
documents.push(text.slice(lastIndex, startIndex)); | |
} | |
lastIndex = startIndex; | |
}); | |
documents.push(text.slice(lastIndex)); | |
return documents; | |
}; | |
// Функция для группировки документов | |
const groupDocuments = (documents: string[], groupSize: number) => { | |
const groups = []; | |
for (let i = 0; i < documents.length; i += groupSize) { | |
groups.push(documents.slice(i, i + groupSize).join("\n")); | |
} | |
return groups; | |
}; | |
// Функция для разделения текста на части, не превышающие 32000 символов | |
const splitLongText = (text: string, maxLength: number) => { | |
const parts = []; | |
for (let i = 0; i < text.length; i += maxLength) { | |
parts.push(text.slice(i, i + maxLength)); | |
} | |
return parts; | |
}; | |
// eslint-disable-next-line @typescript-eslint/no-explicit-any | |
export const downloadExcel = (data: any[]) => { | |
let worksheet; | |
if (data.length === 0) { | |
worksheet = XLSX.utils.aoa_to_sheet([["No Data"]]); | |
} else { | |
const keys = Object.keys(data[0]); | |
const rows = data.flatMap((obj) => { | |
const row = keys.map((key) => obj[key]); | |
const llmPrompt = obj.llmPrompt || ""; | |
const documents = splitDocuments(llmPrompt); | |
const groupedDocuments = groupDocuments(documents, 10); | |
// Сохраняем начало текста до первого документа | |
const initialText = llmPrompt.slice(0, llmPrompt.indexOf(documents[0])); | |
return groupedDocuments.flatMap((group, index) => { | |
const textParts = splitLongText(group, 32000); | |
return textParts.map((part, partIndex) => { | |
if (index === 0 && partIndex === 0) { | |
const newRow = [...row]; | |
newRow[keys.indexOf("llmPrompt")] = initialText + part; | |
return newRow; | |
} else { | |
const emptyRow = new Array(keys.length).fill(""); | |
emptyRow[keys.indexOf("llmPrompt")] = part; | |
return emptyRow; | |
} | |
}); | |
}); | |
}); | |
const renamedKeys = keys.map((key) => ExcelColumnsName[key] || key); | |
worksheet = XLSX.utils.aoa_to_sheet([renamedKeys, ...rows]); | |
} | |
const columnWidth = 25; // Ширина в символах | |
worksheet["!cols"] = new Array(Object.keys(data[0] || {}).length).fill({ | |
wch: columnWidth, | |
}); | |
const workbook = XLSX.utils.book_new(); | |
XLSX.utils.book_append_sheet(workbook, worksheet, "Logs"); | |
// Генерация бинарных данных Excel-файла | |
const wbout = XLSX.write(workbook, { bookType: "xlsx", type: "array" }); | |
// Создание ссылки для скачивания | |
const blob = new Blob([wbout], { type: "application/octet-stream" }); | |
const url = URL.createObjectURL(blob); | |
const a = document.createElement("a"); | |
a.href = url; | |
a.download = "Журнал логов.xlsx"; | |
document.body.appendChild(a); | |
a.click(); | |
document.body.removeChild(a); | |
URL.revokeObjectURL(url); | |
}; | |