Category Archives: Technology

My blog posts related to technology, technical things and, in particular, computers and computer software.

JavaScript: In-browser export to CSV

This function will turn an array of data into a CSV file and get the browser to “download” it. It should also be wrapping and escaping values properly and, because of the BOM, be read correctly when opened in e.g. Excel.

It’s written in TypeScript ("lib": ["ES2017", "DOM"]), but should be easy to “downgrade” to regular JS if needed…

type GetValue <T> = <I extends T>(item: I) => any;
type FieldName <T> = keyof T;

export interface Columns<T> {
  [s: string]: FieldName<T> | GetValue<T>;

const ROW_SEPARATOR = '\r\n';
const UNICODE_BOM = '\uFEFF';

const wrapValue = (value: string) => `"${value}"`;
const escapeValue = (value: string) => (value || '').replace(/"/, '""');

const toHeaderRow = <T> (columns: Columns<T>) => Object

const toRow = <T> (columns: Columns<T>, item: T) => Object
  .map(field => typeof field === 'function' ? field(item) : item[field])

export const exportToCsv = function <T> (data: T[], columns: Columns<T>, filename: string): void {
  const rows = [];


  for (const item of data) {
    rows.push(toRow(columns, item));

  const csv = UNICODE_BOM + rows.join(ROW_SEPARATOR);
  const uri = `data:text/csv;charset=utf-8;header=present,${encodeURIComponent(csv)}`;

  const link = document.createElement('a');
  link.setAttribute('href', uri);
  link.setAttribute('download', filename);
  link.addEventListener('click', () => link.parentNode.removeChild(link));


const users: User[] = [{id: 1, name: 'Alice', isCool: true}, ...];
const columns: Columns<User> = {
  'Id': 'id',
  'Name': 'name',
  'Is cool': user => user.isCool ? 'Yes' : 'No',
exportToCsv(users, columns, 'users.csv');

Fix IntelliJ Alt Gr not working

I’ve several times had the Alt Gr key stop working while using IntelliJ. On norwegian keyboards, this key is essential in typing e.g. the brackets {} and [], so it not working is extremely annoying. And what increases the annoyance even more, is that, when this happens, the key for some reason stops working in other programs too.

Anyways, this seemed to fix it, on my machine at least, for now:

  1. Go to Help \ Edit Custom Properties
  2. Paste in this line:
  3. Restart IntelliJ

What’s running on port 80 in Windows?

Trying to set up Apache on a server, something is hogging port 80, but very “helpfully” the Resource Monitor just reports “System” with PID 4…

However, some commands found in a StackOverflow answer and its comments were helpful:

netsh http show urlacl
netsh http show servicestate
net stop http

Note: Do not just run these commands blindly and turn off services (in particular you should probably answer N when the last one asks…), but use them to identify what service(s) might be to blame. Then do an intelligent decision on whether the service is needed or not, before you potentially stop it and disable it…

Using SSH keys with BitBucket/GitHub on Windows

Couldn’t get this to work, but now it does, so… time for another “note to self”. 🙂


  • Git, obviously…
  • PuTTY, with puttygen, plink and pageant, to be exact…


  1. Open puttygen.
  2. Load your private key, or generate a new one and save it.
  3. Copy your public key (“Public key for pasting …”) to BitBucket/GitHub/etc.
  4. Open pageant
  5. Load your private key.
  6. Check that the key authentication works by running e.g.
    plink -v
    plink -v
  7. Point the GIT_SSH environment variable to plink.exe.

Now, as long as pageant is running with your private key loaded, it should work to clone, pull, push, etc. to/from both private and public repos. E.g. git clone

Key here, for me, was the GIT_SSH variable that so many blogs, StackOverflow answers and forum posts failed to mention… Without that set, the plink check did still work, but git clone did not. It just failed with an authentication error. With that variable set it now works perfectly. 🙄🙂👍