@krutai/excel-comparison 0.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,353 @@
1
+ # AI Reference Guide for @krutai/excel-comparison
2
+
3
+ This document provides comprehensive context for AI assistants to help users integrate and use the excel-comparison library effectively.
4
+
5
+ ## Library Purpose
6
+
7
+ The `@krutai/excel-comparison` library compares Excel (.xlsx, .xls) and CSV files, finding:
8
+ - Matching rows between two files
9
+ - Different values in matching rows
10
+ - Unique rows in each file
11
+ - Generates downloadable Excel reports with differences highlighted
12
+
13
+ ## Core Classes and Exports
14
+
15
+ // Main class - use this for comparing files via API
16
+ import { krutExcelComparison, createComparisonClient } from "@krutai/excel-comparison";
17
+
18
+ // Create client using convenience factory (recommended)
19
+ const client = krutExcelComparison({
20
+ serverUrl: "https://api.krut.ai",
21
+ apiKey: "your-krut-api-key"
22
+ });
23
+
24
+ // Or using createComparisonClient
25
+ const client2 = createComparisonClient({
26
+ apiKey: "..."
27
+ });
28
+
29
+ // API client class
30
+ import { ComparisonApiClient } from "@krutai/excel-comparison";
31
+
32
+ ### Type Exports
33
+
34
+ ```typescript
35
+ import type {
36
+ ComparisonApiResponse, // Result from API comparison
37
+ PreviewResponse, // Preview info for files
38
+ CompareFilesOptions, // Configuration options
39
+ DataRecord, // Row data as object (used in reporting/engine)
40
+ } from "@krutai/excel-comparison";
41
+ ```
42
+
43
+ ## Common Use Cases
44
+
45
+ ### 1. Basic File Comparison (via API)
46
+
47
+ ```typescript
48
+ import { krutExcelComparison } from "@krutai/excel-comparison";
49
+
50
+ const client = krutExcelComparison({
51
+ apiKey: "your-api-key"
52
+ });
53
+
54
+ // For browser - using File objects
55
+ const result = await client.compareFilesFromFileObjects(file1, file2);
56
+
57
+ // For Node.js/Server - using Buffer
58
+ const result2 = await client.compareFiles(buffer1, "file1.xlsx", buffer2, "file2.xlsx");
59
+ ```
60
+
61
+ ### 2. With Comparison Options
62
+
63
+ ```typescript
64
+ const result = await client.compareFilesFromFileObjects(file1, file2, {
65
+ matchColumn: "Invoice", // Optional: column to match rows
66
+ tolerance: 0.01, // Optional: numeric tolerance
67
+ caseSensitive: false, // Optional: case insensitive
68
+ ignoreColumns: ["Timestamp"] // Optional: ignore these columns
69
+ });
70
+ ```
71
+
72
+ ### 3. Preview Files Before Comparison
73
+
74
+ ```typescript
75
+ // Get preview metadata and suggested match columns
76
+ const preview = await client.previewFiles(file1, file2);
77
+
78
+ // Returns:
79
+ {
80
+ success: true,
81
+ file1: { name: "sales.xlsx", rowCount: 100, columns: [...], sample: [...] },
82
+ file2: { name: "sales2.xlsx", rowCount: 95, columns: [...], sample: [...] },
83
+ suggestedMatchColumn: "Invoice"
84
+ }
85
+ ```
86
+
87
+ ### 4. Generate Excel Report
88
+
89
+ ```typescript
90
+ import { StyledReporter } from "@krutai/excel-comparison";
91
+
92
+ const reporter = new StyledReporter({
93
+ headerColor: "4472C4", // Blue header
94
+ differenceColor: "FFCCCC", // Red for differences
95
+ matchColor: "CCFFCC", // Green for matches
96
+ includeSummary: true
97
+ });
98
+
99
+ // Transform comparison results for report
100
+ const reportData = result.results.map((r, i) => ({
101
+ Row: i + 1,
102
+ Status: r.status,
103
+ "Match %": `${r.matchPercentage}%`,
104
+ ...Object.fromEntries(
105
+ result.allColumns.flatMap(col => [
106
+ [`File1_${col}`, r.file1Row?.[col] ?? 'N/A'],
107
+ [`File2_${col}`, r.file2Row?.[col] ?? 'N/A'],
108
+ ])
109
+ )
110
+ }));
111
+
112
+ const report = await reporter.generateReport({
113
+ data: reportData,
114
+ summary: result.summary,
115
+ });
116
+
117
+ // Download as base64
118
+ const downloadUrl = `data:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;base64,${report.toString('base64')}`;
119
+ ```
120
+
121
+ ### 5. Next.js API Route Integration (Recommended)
122
+
123
+ ```typescript
124
+ // app/api/compare/route.ts
125
+ import { NextRequest, NextResponse } from "next/server";
126
+ import {
127
+ createComparisonClient,
128
+ type CompareFilesOptions,
129
+ } from "@krutai/excel-comparison";
130
+
131
+ const SUPPORTED_EXTENSIONS = new Set(["xlsx", "xls", "csv"]);
132
+
133
+ function getFileExtension(fileName: string): string {
134
+ const parts = fileName.toLowerCase().split(".");
135
+ return parts.length > 1 ? parts[parts.length - 1] : "";
136
+ }
137
+
138
+ function isSupportedFile(file: File): boolean {
139
+ return SUPPORTED_EXTENSIONS.has(getFileExtension(file.name));
140
+ }
141
+
142
+ function getComparisonErrorMessage(raw: string): string {
143
+ const lower = raw.toLowerCase();
144
+ if (lower.includes("can't find end of central directory") || lower.includes("zip file")) {
145
+ return "One of the uploaded files is not a valid .xlsx file archive. For Excel inputs, use a valid .xlsx or .xls file.";
146
+ }
147
+ if (lower.includes("request timed out")) {
148
+ return "Comparison request timed out. Please try smaller files or increase the timeout.";
149
+ }
150
+ return raw;
151
+ }
152
+
153
+ function parseIgnoreColumns(value?: string): string[] | undefined {
154
+ if (!value?.trim()) return undefined;
155
+
156
+ if (value.trim().startsWith("[")) {
157
+ try {
158
+ const parsed = JSON.parse(value) as unknown;
159
+ if (Array.isArray(parsed)) {
160
+ return parsed
161
+ .filter((item): item is string => typeof item === "string")
162
+ .map((item) => item.trim())
163
+ .filter(Boolean);
164
+ }
165
+ } catch { }
166
+ }
167
+
168
+ return value.split(",").map(i => i.trim()).filter(Boolean);
169
+ }
170
+
171
+ export async function POST(req: NextRequest) {
172
+ try {
173
+ const formData = await req.formData();
174
+ const file1 = formData.get("file1") as File | null;
175
+ const file2 = formData.get("file2") as File | null;
176
+ const matchColumn = formData.get("matchColumn") as string | undefined;
177
+ const ignoreColumns = formData.get("ignoreColumns") as string | undefined;
178
+ const tolerance = formData.get("tolerance") as string | undefined;
179
+ const caseSensitive = formData.get("caseSensitive") as string | undefined;
180
+
181
+ if (!file1 || !file2) {
182
+ return NextResponse.json({ error: "Both file1 and file2 are required" }, { status: 400 });
183
+ }
184
+
185
+ if (!isSupportedFile(file1) || !isSupportedFile(file2)) {
186
+ return NextResponse.json({ error: "Unsupported file type. Use .xlsx, .xls, or .csv files." }, { status: 400 });
187
+ }
188
+
189
+ const options: CompareFilesOptions = {};
190
+ if (matchColumn?.trim()) options.matchColumn = matchColumn.trim();
191
+ const parsedIgnore = parseIgnoreColumns(ignoreColumns);
192
+ if (parsedIgnore) options.ignoreColumns = parsedIgnore;
193
+ if (tolerance?.trim()) options.tolerance = Number(tolerance);
194
+ if (caseSensitive !== undefined) options.caseSensitive = caseSensitive === "true";
195
+
196
+ const client = createComparisonClient({
197
+ apiKey: process.env.KRUTAI_API_KEY || '',
198
+ serverUrl: process.env.KRUTAI_SERVER_URL || "http://localhost:8000",
199
+ validateOnInit: false,
200
+ });
201
+
202
+ const apiResponse = await client.compareFilesFromFileObjects(file1, file2, options);
203
+
204
+ if (!apiResponse.success || !apiResponse.result) {
205
+ return NextResponse.json({ error: apiResponse.error ?? "Comparison failed" }, { status: 500 });
206
+ }
207
+
208
+ return NextResponse.json({
209
+ success: true,
210
+ result: apiResponse.result,
211
+ results: [],
212
+ allColumns: [...new Set([
213
+ ...(apiResponse.result.metadata.file1Columns ?? []),
214
+ ...(apiResponse.result.metadata.file2Columns ?? []),
215
+ ])],
216
+ columnsWithDiffs: [],
217
+ downloadUrl: apiResponse.downloadUrl,
218
+ fileName: apiResponse.fileName,
219
+ });
220
+ } catch (err: unknown) {
221
+ const msg = err instanceof Error ? err.message : "Comparison failed";
222
+ return NextResponse.json({ error: getComparisonErrorMessage(msg) }, { status: 500 });
223
+ }
224
+ }
225
+ ```
226
+
227
+ ### 6. Express.js Integration
228
+
229
+ ```typescript
230
+ import express from 'express';
231
+ import multer from 'multer';
232
+ import { krutExcelComparison } from "@krutai/excel-comparison";
233
+
234
+ const app = express();
235
+ const upload = multer({ storage: multer.memoryStorage() });
236
+ const client = krutExcelComparison({ apiKey: process.env.KRUTAI_API_KEY });
237
+
238
+ app.post('/compare', upload.fields([
239
+ { name: 'file1', maxCount: 1 },
240
+ { name: 'file2', maxCount: 1 }
241
+ ]), async (req, res) => {
242
+ const files = req.files as { [fieldname: string]: Express.Multer.File[] };
243
+
244
+ const result = await client.compareFiles(
245
+ files.file1[0].buffer, files.file1[0].originalname,
246
+ files.file2[0].buffer, files.file2[0].originalname,
247
+ {
248
+ matchColumn: req.body.matchColumn,
249
+ tolerance: req.body.tolerance ? parseFloat(req.body.tolerance) : undefined
250
+ }
251
+ );
252
+
253
+ res.json(result);
254
+ });
255
+ ```
256
+
257
+ ## ComparisonApiResponse Structure
258
+
259
+ ```typescript
260
+ {
261
+ success: boolean, // true if comparison succeeded
262
+ result?: {
263
+ summary: {
264
+ totalRows: number, // Total rows compared
265
+ matchesFound: number, // Rows with all values matching
266
+ differencesFound: number,// Rows with differences
267
+ uniqueToFile1: number, // Rows only in first file
268
+ uniqueToFile2: number, // Rows only in second file
269
+ status: 'SUCCESS' | 'PARTIAL' | 'NO_MATCH'
270
+ },
271
+ matchColumn: string,
272
+ metadata: {
273
+ file1Name: string,
274
+ file1Columns: string[],
275
+ file1RowCount: number,
276
+ file2Name: string,
277
+ file2Columns: string[],
278
+ file2RowCount: number
279
+ }
280
+ },
281
+ downloadUrl?: string, // URL to download the Excel report
282
+ fileName?: string, // Suggested file name for download
283
+ error?: string // Error message if success is false
284
+ }
285
+ ```
286
+
287
+ ## Key Behaviors
288
+
289
+ ### API Comparison
290
+ - The package now acts as a client for a backend comparison service.
291
+ - It offloads heavy Excel processing and comparison logic to the server.
292
+ - It returns a summary of results and a link to a professionally styled Excel report.
293
+
294
+ ### Column Matching
295
+ - If `matchColumn` is provided, uses that column to match rows
296
+ - If not provided, auto-detects: prioritizes id, invoice, gstin, number, name, code
297
+ - Falls back to first column if no match found
298
+
299
+ ### Value Comparison (Backend)
300
+ - Done on the server side using intelligent algorithms.
301
+ - Supports fuzzy matching, numeric tolerance, and case sensitivity.
302
+
303
+ ## Common Integration Patterns
304
+
305
+ ### Pattern 1: Basic Comparison
306
+ ```typescript
307
+ const client = krutExcelComparison({ apiKey: "..." });
308
+ const result = await client.compareFilesFromFileObjects(f1, f2);
309
+ ```
310
+
311
+ ### Pattern 2: Comparison with Options
312
+ ```typescript
313
+ const result = await client.compareFilesFromFileObjects(f1, f2, {
314
+ matchColumn: "Invoice No",
315
+ tolerance: 0.001,
316
+ caseSensitive: false
317
+ });
318
+ ```
319
+
320
+ ## Error Handling
321
+
322
+ ```typescript
323
+ try {
324
+ const result = await client.compareFilesFromFileObjects(file1, file2);
325
+ } catch (error) {
326
+ if (error.message.includes("Request timed out")) {
327
+ // Handle timeout
328
+ } else {
329
+ // Generic error
330
+ }
331
+ }
332
+ ```
333
+
334
+ ## Package Dependencies
335
+
336
+ The library is lightweight and depends on:
337
+ - `exceljs` - For local reporting (optional)
338
+
339
+ ## Environment Notes
340
+
341
+ - Works in Node.js (v14+) and modern browsers
342
+ - Uses dynamic imports for xlsx to support Next.js
343
+ - File objects from HTML inputs work in browser
344
+ - Buffer objects work in Node.js
345
+
346
+ ## Contributing Guidelines for AI Assistants
347
+
348
+ When helping users with this library:
349
+
350
+ 1. Use `krutExcelComparison` or `ComparisonApiClient`.
351
+ 2. Emphasize that comparison is done via API.
352
+ 3. Show Next.js API route as the primary integration example.
353
+ 4. Note that heavy parsing (xlsx) is done on the backend.
package/README.md ADDED
@@ -0,0 +1,161 @@
1
+ # @krutai/excel-comparison
2
+
3
+ A powerful library for comparing Excel and CSV files by leveraging Backend APIs for high-performance processing.
4
+
5
+ ## Features
6
+
7
+ - **API-Driven Comparison**: Offloads heavy Excel processing to a dedicated comparison service.
8
+ - **Smart Column Matching**: Automatically detects matching columns between files on the server.
9
+ - **Detailed Summaries**: Get row counts, matches, and differences instantly.
10
+ - **Professional Reports**: Automatically generates styled Excel reports with highlighted differences.
11
+ - **Next.js & Serverless Ready**: Optimized for modern web frameworks with zero heavy dependencies like `xlsx`.
12
+
13
+ ## Installation
14
+
15
+ ```bash
16
+ npm install @krutai/excel-comparison
17
+ ```
18
+
19
+ ## Quick Start
20
+
21
+ ### Basic Usage (Server-side)
22
+
23
+ ```typescript
24
+ import { krutExcelComparison } from "@krutai/excel-comparison";
25
+
26
+ // Create client
27
+ const client = krutExcelComparison({
28
+ apiKey: process.env.KRUTAI_API_KEY,
29
+ serverUrl: process.env.KRUTAI_SERVER_URL || "https://api.krut.ai"
30
+ });
31
+
32
+ // Compare files using buffers
33
+ const result = await client.compareFiles(
34
+ file1Buffer, "file1.xlsx",
35
+ file2Buffer, "file2.xlsx",
36
+ { matchColumn: "Invoice" }
37
+ );
38
+
39
+ if (result.success) {
40
+ console.log('Report URL:', result.downloadUrl);
41
+ }
42
+ ```
43
+
44
+ ### Next.js API Route Integration
45
+
46
+ This is the recommended way to use the library in a Next.js application.
47
+
48
+ ```typescript
49
+ // app/api/compare/route.ts
50
+ import { NextRequest, NextResponse } from "next/server";
51
+ import {
52
+ createComparisonClient,
53
+ type CompareFilesOptions,
54
+ } from "@krutai/excel-comparison";
55
+
56
+ const SUPPORTED_EXTENSIONS = new Set(["xlsx", "xls", "csv"]);
57
+
58
+ function getFileExtension(fileName: string): string {
59
+ const parts = fileName.toLowerCase().split(".");
60
+ return parts.length > 1 ? parts[parts.length - 1] : "";
61
+ }
62
+
63
+ function isSupportedFile(file: File): boolean {
64
+ return SUPPORTED_EXTENSIONS.has(getFileExtension(file.name));
65
+ }
66
+
67
+ function parseIgnoreColumns(value?: string): string[] | undefined {
68
+ if (!value?.trim()) return undefined;
69
+ if (value.trim().startsWith("[")) {
70
+ try {
71
+ const parsed = JSON.parse(value);
72
+ if (Array.isArray(parsed)) return parsed.filter(i => typeof i === "string");
73
+ } catch { }
74
+ }
75
+ return value.split(",").map(i => i.trim()).filter(Boolean);
76
+ }
77
+
78
+ export async function POST(req: NextRequest) {
79
+ try {
80
+ const formData = await req.formData();
81
+ const file1 = formData.get("file1") as File | null;
82
+ const file2 = formData.get("file2") as File | null;
83
+ const matchColumn = formData.get("matchColumn") as string | undefined;
84
+
85
+ if (!file1 || !file2) {
86
+ return NextResponse.json({ error: "Both file1 and file2 are required" }, { status: 400 });
87
+ }
88
+
89
+ const client = createComparisonClient({
90
+ apiKey: process.env.KRUTAI_API_KEY || '',
91
+ serverUrl: process.env.KRUTAI_SERVER_URL || "http://localhost:8000"
92
+ });
93
+
94
+ const apiResponse = await client.compareFilesFromFileObjects(file1, file2, {
95
+ matchColumn: matchColumn?.trim()
96
+ });
97
+
98
+ return NextResponse.json(apiResponse);
99
+ } catch (err: unknown) {
100
+ return NextResponse.json({ error: "Comparison failed" }, { status: 500 });
101
+ }
102
+ }
103
+ ```
104
+
105
+ ## API Reference
106
+
107
+ ### krutExcelComparison(config)
108
+
109
+ Convenience factory to create a `ComparisonApiClient`.
110
+
111
+ ### ComparisonApiClient
112
+
113
+ #### `compareFiles(buffer1, name1, buffer2, name2, options)`
114
+ Compare files using Node.js Buffers.
115
+
116
+ #### `compareFilesFromFileObjects(file1, file2, options)`
117
+ Compare files using Web File objects (useful in Browser or Next.js).
118
+
119
+ #### `previewFiles(file1, file2)`
120
+ Get a preview of the files (columns, row counts, and sample data) before committing to a full comparison.
121
+
122
+ ### Types
123
+
124
+ #### ComparisonApiResponse
125
+ ```typescript
126
+ interface ComparisonApiResponse {
127
+ success: boolean;
128
+ result?: {
129
+ summary: {
130
+ totalRows: number;
131
+ matchesFound: number;
132
+ differencesFound: number;
133
+ uniqueToFile1: number;
134
+ uniqueToFile2: number;
135
+ status: 'SUCCESS' | 'PARTIAL' | 'NO_MATCH';
136
+ };
137
+ matchColumn: string;
138
+ metadata: {
139
+ file1Name: string;
140
+ file1Columns: string[];
141
+ file1RowCount: number;
142
+ file2Name: string;
143
+ file2Columns: string[];
144
+ file2RowCount: number;
145
+ };
146
+ };
147
+ downloadUrl?: string; // Link to the Excel report
148
+ fileName?: string;
149
+ error?: string;
150
+ }
151
+ ```
152
+
153
+ ## Supported File Formats
154
+
155
+ - `.xlsx` (Excel 2007+)
156
+ - `.xls` (Excel 97-2003)
157
+ - `.csv` (Comma Separated Values)
158
+
159
+ ## License
160
+
161
+ MIT
@@ -0,0 +1,187 @@
1
+ interface ComparisonClientConfig {
2
+ /**
3
+ * KrutAI API key.
4
+ * Optional: defaults to process.env.KRUTAI_API_KEY
5
+ */
6
+ apiKey?: string;
7
+ /**
8
+ * Base URL of your deployed comparison backend server.
9
+ * @default "http://localhost:8000"
10
+ * @example "https://api.krut.ai"
11
+ */
12
+ serverUrl?: string;
13
+ /**
14
+ * Request timeout in milliseconds.
15
+ * @default 60000
16
+ */
17
+ timeout?: number;
18
+ /**
19
+ * Whether to validate the API key against the server on initialization.
20
+ * @default true
21
+ */
22
+ validateOnInit?: boolean;
23
+ }
24
+ interface CompareFilesOptions {
25
+ matchColumn?: string;
26
+ ignoreColumns?: string[];
27
+ tolerance?: number;
28
+ caseSensitive?: boolean;
29
+ }
30
+ interface FilePreview {
31
+ name: string;
32
+ rowCount: number;
33
+ columns: string[];
34
+ sample: Record<string, unknown>[];
35
+ }
36
+ interface PreviewResponse {
37
+ success: boolean;
38
+ file1?: FilePreview;
39
+ file2?: FilePreview;
40
+ suggestedMatchColumn?: string;
41
+ error?: string;
42
+ }
43
+ interface ComparisonApiResponse {
44
+ success: boolean;
45
+ result?: {
46
+ summary: {
47
+ totalRows: number;
48
+ matchesFound: number;
49
+ differencesFound: number;
50
+ uniqueToFile1: number;
51
+ uniqueToFile2: number;
52
+ status: 'SUCCESS' | 'PARTIAL' | 'NO_MATCH';
53
+ };
54
+ matchColumn: string;
55
+ metadata: {
56
+ file1Name: string;
57
+ file1Columns: string[];
58
+ file1RowCount: number;
59
+ file2Name: string;
60
+ file2Columns: string[];
61
+ file2RowCount: number;
62
+ };
63
+ };
64
+ downloadUrl?: string;
65
+ fileName?: string;
66
+ error?: string;
67
+ }
68
+ declare class ComparisonApiClient {
69
+ private serverUrl;
70
+ private apiKey?;
71
+ private timeout;
72
+ private initialized;
73
+ private validateOnInit;
74
+ private initializationPromise;
75
+ constructor(config: ComparisonClientConfig);
76
+ /**
77
+ * Initialize the client.
78
+ * Validates the API key against the server if validateOnInit is true.
79
+ * @throws {Error} If validation fails or API key is missing
80
+ */
81
+ initialize(): Promise<void>;
82
+ private getHeaders;
83
+ private request;
84
+ compareFiles(file1Buffer: Buffer, file1Name: string, file2Buffer: Buffer, file2Name: string, compareOptions?: CompareFilesOptions): Promise<ComparisonApiResponse>;
85
+ compareFilesFromFileObjects(file1: File, file2: File, compareOptions?: CompareFilesOptions): Promise<ComparisonApiResponse>;
86
+ previewFiles(file1: File, file2: File): Promise<PreviewResponse>;
87
+ previewFilesFromBuffers(file1Buffer: Buffer, file1Name: string, file2Buffer: Buffer, file2Name: string): Promise<PreviewResponse>;
88
+ }
89
+ declare function createComparisonClient(config: ComparisonClientConfig): ComparisonApiClient;
90
+
91
+ interface DataRecord {
92
+ [key: string]: unknown;
93
+ }
94
+ interface ComparisonResult {
95
+ data: DataRecord[];
96
+ summary: {
97
+ totalRows: number;
98
+ differencesFound: number;
99
+ matchesFound: number;
100
+ status: 'SUCCESS' | 'PARTIAL' | 'NO_MATCH';
101
+ };
102
+ metadata?: {
103
+ file1Columns?: string[];
104
+ file2Columns?: string[];
105
+ executionTime?: number;
106
+ };
107
+ }
108
+ interface ExcelLoaderOptions {
109
+ sheetIndex?: number;
110
+ sheetName?: string;
111
+ headerRow?: number;
112
+ skipRows?: number;
113
+ sampleRows?: number;
114
+ }
115
+ interface LoaderOptions {
116
+ sheetName?: string;
117
+ headerRow?: number;
118
+ skipRows?: number;
119
+ }
120
+ interface ReporterOptions {
121
+ headerColor?: string;
122
+ differenceColor?: string;
123
+ matchColor?: string;
124
+ sheetName?: string;
125
+ includeSummary?: boolean;
126
+ }
127
+ interface EngineOptions {
128
+ timeout?: number;
129
+ maxMemory?: number;
130
+ }
131
+ interface CodeGenerationResult {
132
+ code: string;
133
+ humanExplanation: string[];
134
+ constants?: Record<string, unknown>;
135
+ }
136
+ interface ComparisonRequest {
137
+ file1Data: DataRecord[];
138
+ file2Data: DataRecord[];
139
+ file1Columns?: string[];
140
+ file2Columns?: string[];
141
+ file1Sample?: DataRecord[];
142
+ file2Sample?: DataRecord[];
143
+ prompt?: string;
144
+ }
145
+ interface ExcelSchema {
146
+ headers: string[];
147
+ rowCount: number;
148
+ columnCount: number;
149
+ sample: DataRecord[];
150
+ data: DataRecord[];
151
+ }
152
+
153
+ declare class StyledReporter {
154
+ private options;
155
+ constructor(options?: ReporterOptions);
156
+ generateReport(result: ComparisonResult, _file1Columns?: string[], _file2Columns?: string[]): Promise<Buffer>;
157
+ private addSummarySheet;
158
+ private addResultSheet;
159
+ private formatValue;
160
+ generateDetailedReport(result: ComparisonResult, file1Columns?: string[], file2Columns?: string[]): Promise<Buffer>;
161
+ private addDataSheet;
162
+ }
163
+
164
+ interface ExcelDataFrame {
165
+ headers: string[];
166
+ data: DataRecord[];
167
+ rowCount: number;
168
+ columnCount: number;
169
+ sample: DataRecord[];
170
+ }
171
+ declare class DataLoader {
172
+ static loadFromBuffer(buffer: Buffer, fileName: string, options?: ExcelLoaderOptions): Promise<ExcelDataFrame>;
173
+ static getColumnNames(data: DataRecord[]): string[];
174
+ static getSampleData(data: DataRecord[], count?: number): DataRecord[];
175
+ }
176
+
177
+ /**
178
+ * krutExcelComparison — convenience factory.
179
+ *
180
+ * Creates a `ComparisonApiClient` instance configured to call the Krut comparison server.
181
+ *
182
+ * @param config - Client configuration (apiKey and serverUrl)
183
+ * @returns A `ComparisonApiClient` instance
184
+ */
185
+ declare function krutExcelComparison(config: ComparisonClientConfig): ComparisonApiClient;
186
+
187
+ export { type FilePreview as ApiFilePreview, type CodeGenerationResult, type CompareFilesOptions, ComparisonApiClient, type ComparisonApiResponse, type ComparisonClientConfig, type ComparisonRequest, type ComparisonResult, DataLoader, type DataRecord, type EngineOptions, type ExcelLoaderOptions, type ExcelSchema, type LoaderOptions, type PreviewResponse, type ReporterOptions, StyledReporter, createComparisonClient, krutExcelComparison };