Spaces:
Sleeping
Sleeping
| 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); | |
| }; | |