0

List Tables

by
Published today

List the tables of a workbook, or of one worksheet. A table is a named range with a header row (Insert > Table in Excel); the table scripts take its name. `workbook` is the .xlsx file's id, or its path from the drive root (e.g. `/Reports/budget.xlsx`). Work or school accounts only. Requires Files.ReadWrite (a connection default); a workbook in a drive that is not your own needs Files.ReadWrite.All.

Script ms_excel Verified

The script

Submitted by hugo989 Typescript (fetch-only)
Verified 5 hours ago
1
//native
2

3
const graph = "https://graph.microsoft.com/v1.0"
4

5
// A workbook is addressed by its drive item id, or by a path from the drive root starting with "/"
6
function workbookUrl(workbook: string, drive_id: string | undefined) {
7
  const drive =
8
    drive_id != null && drive_id !== ""
9
      ? `${graph}/drives/${encodeURIComponent(drive_id)}`
10
      : `${graph}/me/drive`
11
  const item = workbook.startsWith("/")
12
    ? `root:${workbook.split("/").map(encodeURIComponent).join("/")}:`
13
    : `items/${encodeURIComponent(workbook)}`
14
  return `${drive}/${item}/workbook`
15
}
16

17
// Requests without a session can read a copy that lags a minute behind the last write;
18
// a new session always opens the current workbook
19
async function workbookSession(auth: RT.MsExcel, wb: string) {
20
  const response = await fetch(`${wb}/createSession`, {
21
    method: "POST",
22
    headers: {
23
      Authorization: `Bearer ${auth.token}`,
24
      "Content-Type": "application/json",
25
      Accept: "application/json",
26
    },
27
    body: JSON.stringify({ persistChanges: true }),
28
  })
29
  if (!response.ok) {
30
    throw new Error(`${response.status} ${await response.text()}`)
31
  }
32
  return ((await response.json()) as { id: string }).id
33
}
34

35
export type DynSelect_workbook = string
36

37
export async function workbook(
38
  auth: RT.MsExcel,
39
  drive_id: string | undefined
40
) {
41
  const drive =
42
    drive_id != null && drive_id !== ""
43
      ? `${graph}/drives/${encodeURIComponent(drive_id)}`
44
      : `${graph}/me/drive`
45
  const response = await fetch(
46
    `${drive}/root/search(q='.xlsx')?$select=id,name&$top=200`,
47
    {
48
      headers: {
49
        Authorization: `Bearer ${auth.token}`,
50
        Accept: "application/json",
51
      },
52
    }
53
  )
54
  if (!response.ok) {
55
    throw new Error(`${response.status} ${await response.text()}`)
56
  }
57
  const { value } = (await response.json()) as {
58
    value: { id: string; name: string }[]
59
  }
60
  return value
61
    .filter((f) => f.name.toLowerCase().endsWith(".xlsx"))
62
    .map((f) => ({ value: f.id, label: f.name }))
63
}
64

65
export type DynSelect_worksheet = string
66

67
export async function worksheet(
68
  auth: RT.MsExcel,
69
  workbook: string,
70
  drive_id: string | undefined
71
) {
72
  const wb = workbookUrl(workbook, drive_id)
73
  const session = await workbookSession(auth, wb)
74
  const response = await fetch(`${wb}/worksheets?$select=name`, {
75
    headers: {
76
      Authorization: `Bearer ${auth.token}`,
77
      Accept: "application/json",
78
      "workbook-session-id": session,
79
    },
80
  })
81
  if (!response.ok) {
82
    throw new Error(`${response.status} ${await response.text()}`)
83
  }
84
  const { value } = (await response.json()) as { value: { name: string }[] }
85
  return value.map((w) => ({ value: w.name, label: w.name }))
86
}
87

88
/**
89
 * List Tables
90
 * List the tables of a workbook, or of one worksheet. A table is a named range with a header row (Insert > Table in Excel); the table scripts take its name. `workbook` is the .xlsx file's id, or its path from the drive root (e.g. `/Reports/budget.xlsx`). Work or school accounts only. Requires Files.ReadWrite (a connection default); a workbook in a drive that is not your own needs Files.ReadWrite.All.
91
 */
92
export async function main(
93
  auth: RT.MsExcel,
94
  workbook: DynSelect_workbook,
95
  worksheet: DynSelect_worksheet | undefined,
96
  drive_id: string | undefined
97
) {
98
  const wb = workbookUrl(workbook, drive_id)
99
  const session = await workbookSession(auth, wb)
100
  const response = await fetch(
101
    `${worksheet != null && worksheet !== "" ? `${wb}/worksheets/${encodeURIComponent(worksheet)}` : wb}/tables`,
102
    {
103
      headers: {
104
        Authorization: `Bearer ${auth.token}`,
105
        Accept: "application/json",
106
        "workbook-session-id": session,
107
      },
108
    }
109
  )
110

111
  if (!response.ok) {
112
    throw new Error(`${response.status} ${await response.text()}`)
113
  }
114

115
  return await response.json()
116
}
117