import React, { useState } from 'react'; import * as XLSX from 'xlsx'; import { saveAs } from 'file-saver'; import { Button, Container, Row, Col, Form } from 'react-bootstrap'; const ExcelComparison = () => { const [file1, setFile1] = useState(null); const [file2, setFile2] = useState(null); const [comparisonResult, setComparisonResult] = useState({ matchedCount: 0, unmatchedCount: 0 }); const [download1, setDownload1] = useState(null); const [download2, setDownload2] = useState(null); const handleFileChange = (e, setFile) => { const file = e.target.files[0]; setFile(file); }; const handleCompare = () => { if (!file1 || !file2) { alert('Please upload both Excel files.'); return; } const reader1 = new FileReader(); const reader2 = new FileReader(); reader1.onload = (e1) => { const workbook1 = XLSX.read(e1.target.result, { type: 'binary' }); const sheet1 = XLSX.utils.sheet_to_json(workbook1.Sheets[workbook1.SheetNames[0]], { header: 1 }); reader2.onload = (e2) => { const workbook2 = XLSX.read(e2.target.result, { type: 'binary' }); const sheet2 = XLSX.utils.sheet_to_json(workbook2.Sheets[workbook2.SheetNames[0]], { header: 1 }); // Prepare columns for comparison and results let matchedCount = 0; const header1 = sheet1[0]; const header2 = sheet2[0]; const data1 = sheet1.slice(1); const data2 = sheet2.slice(1); data1.forEach((row1, index1) => { const row2 = data2.find(row2 => row2[header2.indexOf('GSTIN of supplier')] === row1[header1.indexOf('GSTIN')] && row2[header2.indexOf('Invoice number')] === row1[header1.indexOf('Invoice No.')]); if (row2) { let matched = 'Matched'; let unmatchedValues = []; if (row1[header1.indexOf('IGST')] !== row2[header2.indexOf('Integrated Tax(₹)')]) { matched = 'Unmatched'; unmatchedValues.push(`IGST: ${row1[header1.indexOf('IGST')]} vs ${row2[header2.indexOf('Integrated Tax(₹)')]}`); } if (row1[header1.indexOf('CGST')] !== row2[header2.indexOf('Central Tax(₹)')]) { matched = 'Unmatched'; unmatchedValues.push(`CGST: ${row1[header1.indexOf('CGST')]} vs ${row2[header2.indexOf('Central Tax(₹)')]}`); } row1.push(matched); row1.push(unmatchedValues.length ? unmatchedValues.join(', ') : ''); row1.push(row2[header2.indexOf('GSTR2B month')]); if (matched === 'Matched') { matchedCount++; } } else { row1.push('Unmatched'); row1.push('GSTIN or Invoice Number'); row1.push(''); } }); const unmatchedCount = data1.length - matchedCount; setComparisonResult({ matchedCount, unmatchedCount }); // Add new headers const updatedHeader1 = [...header1, 'Matched/Unmatched', 'Unmatched Value', '2B MONTH']; const updatedSheet1 = [updatedHeader1, ...data1]; const updatedSheet2 = [header2, ...data2]; const updatedWorkbook1 = XLSX.utils.book_new(); const updatedWorkbook2 = XLSX.utils.book_new(); XLSX.utils.book_append_sheet(updatedWorkbook1, XLSX.utils.aoa_to_sheet(updatedSheet1), 'Sheet1'); XLSX.utils.book_append_sheet(updatedWorkbook2, XLSX.utils.aoa_to_sheet(updatedSheet2), 'Sheet2'); setDownload1(updatedWorkbook1); setDownload2(updatedWorkbook2); }; reader2.readAsBinaryString(file2); }; reader1.readAsBinaryString(file1); }; const handleDownload = (workbook, filename) => { const wbout = XLSX.write(workbook, { bookType: 'xlsx', type: 'binary' }); const buffer = new ArrayBuffer(wbout.length); const view = new Uint8Array(buffer); for (let i = 0; i < wbout.length; i++) view[i] = wbout.charCodeAt(i) & 0xff; saveAs(new Blob([buffer], { type: 'application/octet-stream' }), filename); }; return ( <Container> <h2>Excel File Comparison</h2> <Row className="mb-3"> <Col> <Form.Group> <Form.Label>Upload 1st Excel File</Form.Label> <Form.Control type="file" accept=".xlsx" onChange={(e) => handleFileChange(e, setFile1)} /> </Form.Group> </Col> <Col> <Form.Group> <Form.Label>Upload 2nd Excel File</Form.Label> <Form.Control type="file" accept=".xlsx" onChange={(e) => handleFileChange(e, setFile2)} /> </Form.Group> </Col> </Row> <Button variant="primary" onClick={handleCompare}>Compare</Button> {comparisonResult.matchedCount > 0 && ( <Row className="mt-3"> <Col> <p>Matched Rows: {comparisonResult.matchedCount}</p> <Button variant="success" onClick={() => handleDownload(download1, 'Updated_File1.xlsx')}>Download Updated File 1</Button> </Col> <Col> <p>Unmatched Rows: {comparisonResult.unmatchedCount}</p> <Button variant="success" onClick={() => handleDownload(download2, 'Updated_File2.xlsx')}>Download Updated File 2</Button> </Col> </Row> )} </Container> ); }; export default ExcelComparison;
Preview:
downloadDownload PNG
downloadDownload JPEG
downloadDownload SVG
Tip: You can change the style, width & colours of the snippet with the inspect tool before clicking Download!
Click to optimize width for Twitter