Skip to content

Commit

Permalink
feat: Add Microsoft Excel support (xlsx)
Browse files Browse the repository at this point in the history
Closes: #1489

Signed-off-by: Alexander Alemayhu <[email protected]>
  • Loading branch information
aalemayhu committed Dec 27, 2024
1 parent 72126a2 commit 1e3f2a0
Show file tree
Hide file tree
Showing 12 changed files with 223 additions and 114 deletions.
106 changes: 105 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@
"react": "^18.2.0",
"react-dom": "^18.2.0",
"showdown": "^2.1.0",
"stripe": "^16.8.0"
"stripe": "^16.8.0",
"xlsx": "^0.18.5"
},
"devDependencies": {
"@types/base-64": "^1.0.0",
Expand Down Expand Up @@ -98,4 +99,4 @@
"ts-node": "^10.9.1",
"typescript": "^5.2.2"
}
}
}
11 changes: 11 additions & 0 deletions src/infrastracture/adapters/fileConversion/PrepareDeck.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@ import {
isImageFile,
isPDFFile,
isPPTFile,
isXLSXFile,
} from '../../../lib/storage/checks';
import { convertPDFToHTML } from './convertPDFToHTML';
import { convertPPTToPDF } from './ConvertPPTToPDF';
import { convertImageToHTML } from './convertImageToHTML';
import { convertPDFToImages } from './convertPDFToImages';
import { convertXLSXToHTML } from './convertXLSXToHTML';

interface PrepareDeckResult {
name: string;
Expand All @@ -28,6 +30,15 @@ export async function PrepareDeck(
continue;
}

if (isXLSXFile(file.name)) {
const htmlContent = convertXLSXToHTML(file.contents as Buffer, file.name);
convertedFiles.push({
name: `${file.name}.html`,
contents: Buffer.from(htmlContent),
});
continue;
}

if (
isImageFile(file.name) &&
input.settings.imageQuizHtmlToAnki &&
Expand Down
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { readFileSync } from 'fs';
import Workspace from '../../../../lib/parser/WorkSpace';
import { convertXLSXToHTML } from '../convertXLSXToHTML';
import { join } from 'path';

describe('convertXLSXToHTML', () => {
beforeAll(() => {
process.env.WORKSPACE_BASE = '/tmp';
});

it('should convert XLSX to HTML and save the file', async () => {
const workspace = new Workspace(true, 'fs');
const xlsxPath = join(__dirname, '../___mock/sim.xlsx');
const buffer = readFileSync(xlsxPath);
const html = convertXLSXToHTML(buffer, join(workspace.location, 'Simple.html'));
expect(html).toContain('<!DOCTYPE html>');
expect(html).toContain('Simple.html');
});

afterAll(() => {
delete process.env.WORKSPACE_BASE;
});
});
33 changes: 33 additions & 0 deletions src/infrastracture/adapters/fileConversion/convertXLSXToHTML.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import * as XLSX from 'xlsx';

type XLSXRow = [string | undefined, string | undefined, ...unknown[]];

export function convertXLSXToHTML(buffer: Buffer, title: string): string {
const workbook = XLSX.read(buffer, { type: 'buffer' });
const sheetName = workbook.SheetNames[0];
const worksheet = workbook.Sheets[sheetName];
const jsonData = XLSX.utils.sheet_to_json(worksheet, {
header: 1,
}) as XLSXRow[];

return `<!DOCTYPE html>
<html>
<head><title>${title}</title></head>
<body>
${jsonData
.map((row: XLSXRow) => {
const front = row[0] || '';
const back = row[1] || '';
return `<ul class="toggle">
<li>
<details>
<summary>${front}</summary>
<p>${back}</p>
</details>
</li>
</ul>`;
})
.join('\n')}
</body>
</html>`;
}
107 changes: 0 additions & 107 deletions src/lib/parser/PrepareDeck.ts

This file was deleted.

Loading

0 comments on commit 1e3f2a0

Please sign in to comment.