Skip to content
This repository was archived by the owner on Feb 9, 2026. It is now read-only.

Commit 7f1de4e

Browse files
authored
Merge pull request #132 from u-hossy/feature/add-csv
Feature/add csv
2 parents 7911460 + 313556c commit 7f1de4e

File tree

3 files changed

+59
-0
lines changed

3 files changed

+59
-0
lines changed

frontend/src/lib/downloadCsv.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
function downloadCsv(csv: string, filename = "result.csv") {
2+
const blob = new Blob([csv], { type: "text/csv;charset=utf-8;" });
3+
const url = URL.createObjectURL(blob);
4+
const link = document.createElement("a");
5+
link.href = url;
6+
link.download = filename;
7+
document.body.appendChild(link);
8+
link.click();
9+
link.remove();
10+
}
11+
12+
export { downloadCsv };

frontend/src/lib/generateCsv.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import type { Member } from "@/types/member";
2+
import type { Result } from "@/types/result";
3+
4+
function generateCsv(members: Member[], results: Result[]): string {
5+
const idToName = Object.fromEntries(members.map((m) => [m.id, m.name]));
6+
7+
const people = Array.from(
8+
new Set(
9+
results
10+
.map((r) => idToName[r.paidBy])
11+
.concat(results.map((r) => idToName[r.paidFor])),
12+
),
13+
);
14+
15+
const matrix: Record<string, Record<string, number>> = {};
16+
people.forEach((from) => {
17+
matrix[from] = {};
18+
people.forEach((to) => (matrix[from][to] = 0));
19+
});
20+
21+
results.forEach((r) => {
22+
const from = idToName[r.paidBy];
23+
const to = idToName[r.paidFor];
24+
matrix[from][to] += r.amount;
25+
});
26+
27+
const header = ["支払う\\受け取る", ...people].join(",");
28+
29+
const rows = people.map((from) => {
30+
const amounts = people.map((to) => matrix[from][to]);
31+
return [from, ...amounts].join(",");
32+
});
33+
34+
return [header, ...rows].join("\n");
35+
}
36+
37+
export { generateCsv };

frontend/src/pages/AlgorithmAndResultPage.tsx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@ import { useNavigate, useParams } from "react-router-dom";
33
import NetworkGraph from "@/components/NetworkGraph";
44
import SelectAlgorithm from "@/components/SelectAlgorithm";
55
import { deleteResult } from "@/lib/deleteResult";
6+
import { downloadCsv } from "@/lib/downloadCsv";
67
import { fetchResult } from "@/lib/fetchResult";
8+
import { generateCsv } from "@/lib/generateCsv";
79
import { getResult } from "@/lib/getResult";
810
import { saveResult } from "@/lib/saveResult";
911
import type { Payment } from "@/types/payment";
@@ -52,6 +54,11 @@ export default function AlgorithmAndResultPage({ payments, members }: Props) {
5254
}
5355
};
5456

57+
const handleCsvExport = () => {
58+
const csv = generateCsv(members, results);
59+
downloadCsv(csv);
60+
};
61+
5562
useEffect(() => {
5663
const loadSavedResults = async () => {
5764
if (!eventId) return;
@@ -111,6 +118,9 @@ export default function AlgorithmAndResultPage({ payments, members }: Props) {
111118
>
112119
戻る
113120
</Button>
121+
<Button onClick={handleCsvExport} size="lg">
122+
CSV出力
123+
</Button>
114124
</div>
115125
</CardWrapper>
116126

0 commit comments

Comments
 (0)