Exporting HTML Table to Excel [.xls, .csv] using JavaScript Tutorial

In this tutorial, you will learn how to Export HTML Table Data to Excel Spreadsheets and CSV Files using JavaScript. This tutorial aims to provide the IT/CS student and new programmers with a reference to learn to export Data into Excel using only Pure JavaScript. Here, I will provide sample snippets on how to achieve this tutorial's objectives. A working sample program source code zip file is also provided and is free to download.

In some programs or web applications, the management often requires an export of data from the system to excel spreadsheets or CSV files. Mostly, the purpose of this feature is to extract the data that allows the system management to use it for some other purpose. Export to Excel features is commonly implemented along with the report feature of the program.

How to Export HTML Table to Excel File using JS?

There are a lot of ways to Export Table Data to CSV or Excel Spreadsheet. Some developers preferred to use free plugins or libraries to make it possible. Using JavaScript built-in methods and short lines of script, we can also achieve the said feature for our web application. JavaScript comes with a Blob object which is very helpful to achieve our goal here. We can simply generate a file-like raw data of the HTML Table and create an object URL to put in an anchor tag which enables us to download the file.

What is JS Blob?

A blob is an immutable, file-like object with raw data; it can be read as text or binary data or turned into a ReadableStream so that its methods can be used to process the data. The JavaScript's Blob object represents blobs.

Steps of Exporting Table Data to Excel [.xls, .csv]?

Export as Excel Spreadsheet File

  1. Get the Table outer HTML in JS and put it into a new HTML document string
  2. Convert the HTML document string into a Blob object using the application/vnd.openxmlformats-officedocument.spreadsheetml.sheet content-type.
  3. Create an Anchor Element
  4. Set a download attribute to the anchor with the filename as the value i.e exportedData.xls
  5. Create an Object URL of the Blob object and set it into the anchor's href attribute
  6. Append the Anchor Tag to the page document body
  7. Trigger Click the Anchor Tag to download the exported file

Export as CSV File

  1. Get the Table outer HTML in JS and put it into a new HTML document string
  2. Convert the HTML document string into a Blob object using the text/csv content type.
  3. Create an Anchor Element
  4. Set a download attribute to the anchor with the filename as the value i.e exportedData.csv
  5. Create an Object URL of the Blob object and set it into the anchor's href attribute
  6. Append the Anchor Tag to the page document body
  7. Trigger Click the Anchor Tag to download the exported file

Snippets

How to Export HTML Table to Excel Spreadsheet?

Using the following snippet, we can export the Table Data into a (.xls) or Excel Spreadsheet File easily. The following script uses the Blob object to convert HTML into a blob using the application/vnd.openxmlformats-officedocument.spreadsheetml.sheet content type.

  1. document.getElementById("exportTable").addEventListener("click", function(e){
  2.  
  3. e.preventDefault()
  4.  
  5. var _tbl = document.getElementById('exampleTbl').outerHTML
  6.  
  7. var excel_content = `<html><body>${_tbl}</body></html>`
  8.  
  9. var file = new Blob([excel_content], {type:'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'});
  10. var dl_anchor = document.createElement('a')
  11. dl_anchor.style.display = this.nonce;
  12. dl_anchor.download = "tableData.xls";
  13. dl_anchor.href = window.URL.createObjectURL(file);
  14.  
  15. document.body.appendChild(dl_anchor)
  16. dl_anchor.click()
  17.  
  18. })

How to Export HTML Table to CSV?

The following snippet has a similarity to the first snippet I provided. The only difference is that the table data was extracted from the table cells. The table rows are separated with (\r\n) or next line delimiter and each cell of the row is separated using the comma (,). Aside from that, the Blob content type must be text/csv.

  1. document.getElementById("exportTableCSV").addEventListener("click", function(e){
  2.  
  3. e.preventDefault()
  4.  
  5. var _tbl_rows = document.querySelectorAll('#exampleTbl tr')
  6. var csv ="";
  7. var rows = []
  8. _tbl_rows.forEach(el => {
  9. var row = []
  10. el.querySelectorAll('th, td').forEach(ele => {
  11. var ele_clone = ele.cloneNode(true)
  12. ele_clone.innerText = (ele_clone.innerText).replace(/\"/gi, '\"\"')
  13. ele_clone.innerText = ('"' + ele_clone.innerText + '"')
  14. row.push(ele_clone.innerText)
  15. })
  16. rows.push(row.join(","));
  17. })
  18. csv += rows.join(`\r\n`)
  19. var file = new Blob([csv], {type:'text/csv'});
  20. var dl_anchor = document.createElement('a')
  21. dl_anchor.style.display = this.nonce;
  22. dl_anchor.download = "tableCsv.csv";
  23. dl_anchor.href = window.URL.createObjectURL(file);
  24.  
  25. document.body.appendChild(dl_anchor)
  26. dl_anchor.click()
  27. })

Using the JavaScript snippets that I provided above, we can achieve our goal and objective of this tutorial which is to export Table Data to an Excel Spreadsheet and CSV File. The following is the snippet of a simple program that demonstrates the usage of the given snippet above.

Example

Interface

Assuming that we have an application page with an HTML Table that displays a list of record. Here's an example script of an application page interface. The script is known as an index.html file.

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <meta charset="UTF-8">
  4. <meta http-equiv="X-UA-Compatible" content="IE=edge">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <title>JavaScript - Table to Excel</title>
  7. <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.0/css/all.min.css" integrity="sha512-xh6O/CkQoPOWDdYTDqeRdPCVd1SpvCA9XXcUnZS2FmJNp1coAFzvtCN9BmamE+4aHK8yyUHUSCcJHgXloTyT2A==" crossorigin="anonymous" referrerpolicy="no-referrer" />
  8. <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" integrity="sha384-Zenh87qX5JnK2Jl0vWa8Ck2rdkQ2Bzep5IDxbcnCeuOxjzrPF/et3URy9Bv1WTRi" crossorigin="anonymous">
  9.  
  10. <script src="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.0/js/all.min.js" integrity="sha512-naukR7I+Nk6gp7p5TMA4ycgfxaZBJ7MO5iC3Fp6ySQyKFHOGfpkSZkYVWV5R7u7cfAicxanwYQ5D1e17EfJcMA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
  11. <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-OERcA2EqjJCMA+/3y+gxIOqMEjwtxJY7qPCqsdltbNJuaOe923+mo//f6V8Qbsw3" crossorigin="anonymous"></script>
  12.  
  13. html, body{
  14. height: 100%;
  15. width: 100%;
  16. }
  17. body{
  18. display: flex;
  19. height: 100%;
  20. width: 100%;
  21. flex-direction: column;
  22. }
  23. body>nav, body>footer{
  24. flex-shrink: 1;
  25. }
  26. body>main{
  27. flex-shrink: 1;
  28. flex-grow: 1;
  29. overflow: auto;
  30. margin: 1em 0;
  31. }
  32. pre{
  33. min-height:20vh
  34. }
  35. </style>
  36. </head>
  37. <body style="background:#eff3fc">
  38. <nav class="navbar navbar-expand-lg navbar-dark" style="background:#495C83">
  39. <div class="container">
  40. <a class="navbar-brand" href="./">JavaScript - Table to Excel</a>
  41. <div>
  42. <a href="https://sourcecodester.com" class="text-light fw-bolder h6 text-decoration-none" target="_blank">SourceCodester</a>
  43. </div>
  44. </div>
  45. </nav>
  46.  
  47. <main class="container-fluid">
  48. <div class="col-lg-10 col-md-11 col-sm-12 col-xs-12 mx-auto">
  49. <h2 class="text-center">Exporting Table to Excel using JavaScript</h2>
  50. <hr>
  51.  
  52. <div class="card mt-3 rounded-0">
  53. <div class="card-header">
  54. <div class="d-flex justify-content-between align-items-end">
  55. <div class="col-auto flex-shrink-1 flex-grow-1">
  56. <div class="card-title"><b>Sample HTML Table Data</b></div>
  57. </div>
  58. <div class="col-auto flex-shrink-1">
  59. <button class="btn btn-sm btn-primary rounded-0 btn-success bg-gradient bg-success me-2" id="exportTable">Export to Excel</button>
  60. <button class="btn btn-sm btn-primary rounded-0 btn-primary bg-gradient bg-primary" id="exportTableCSV">Export to CSV</button>
  61. </div>
  62. </div>
  63. </div>
  64. <div class="card-body rounded-0">
  65. <div class="container-fluid">
  66. <div class="table-responsive">
  67. <table class="table table-hover table-striped table-bordered" id="exampleTbl">
  68. <tr class="bg-gradient bg-primary text-light">
  69. <th class="text-center px-2 py1">Name</th>
  70. <th class="text-center px-2 py1">Phone</th>
  71. <th class="text-center px-2 py1">Email</th>
  72. <th class="text-center px-2 py1">Address</th>
  73. <th class="text-center px-2 py1">Region</th>
  74. <th class="text-center px-2 py1">Postal</th>
  75. <th class="text-center px-2 py1">Country</th>
  76. </tr>
  77. </thead>
  78. <tr>
  79. <td class="px-2 py-1">Aquila Buckner</td>
  80. <td class="px-2 py-1">1-606-851-8687</td>
  81. <td class="px-2 py-1">[email protected]</td>
  82. <td class="px-2 py-1">2784 Lorem, St.</td>
  83. <td class="px-2 py-1">Noord Holland</td>
  84. <td class="px-2 py-1">41381</td>
  85. <td class="px-2 py-1">France</td>
  86. </tr>
  87. <tr>
  88. <td class="px-2 py-1">Joseph Mclaughlin</td>
  89. <td class="px-2 py-1">(287) 727-2636</td>
  90. <td class="px-2 py-1">[email protected]</td>
  91. <td class="px-2 py-1">Ap #299-1793 Enim Avenue</td>
  92. <td class="px-2 py-1">Västra Götalands län</td>
  93. <td class="px-2 py-1">15-933</td>
  94. <td class="px-2 py-1">Netherlands</td>
  95. </tr>
  96. <tr>
  97. <td class="px-2 py-1">Freya Gilbert</td>
  98. <td class="px-2 py-1">1-962-676-7616</td>
  99. <td class="px-2 py-1">[email protected]</td>
  100. <td class="px-2 py-1">724-3255 Praesent Avenue</td>
  101. <td class="px-2 py-1">North Jeolla</td>
  102. <td class="px-2 py-1">218533</td>
  103. <td class="px-2 py-1">Turkey</td>
  104. </tr>
  105. <tr>
  106. <td class="px-2 py-1">Zephania Hancock</td>
  107. <td class="px-2 py-1">(543) 609-4676</td>
  108. <td class="px-2 py-1">[email protected]</td>
  109. <td class="px-2 py-1">Ap #907-4861 Gravida St.</td>
  110. <td class="px-2 py-1">Carinthia</td>
  111. <td class="px-2 py-1">892505</td>
  112. <td class="px-2 py-1">India</td>
  113. </tr>
  114. <tr>
  115. <td class="px-2 py-1">Michelle Bowman</td>
  116. <td class="px-2 py-1">1-906-704-3417</td>
  117. <td class="px-2 py-1">[email protected]</td>
  118. <td class="px-2 py-1">Ap #705-2692 Diam. Avenue</td>
  119. <td class="px-2 py-1">Quebec</td>
  120. <td class="px-2 py-1">87856-202</td>
  121. <td class="px-2 py-1">United States</td>
  122. </tr>
  123. <tr>
  124. <td class="px-2 py-1">Hadassah Lyons</td>
  125. <td class="px-2 py-1">1-491-838-9458</td>
  126. <td class="px-2 py-1">[email protected]</td>
  127. <td class="px-2 py-1">P.O. Box 810, 2499 Hendrerit. Avenue</td>
  128. <td class="px-2 py-1">Tarapacá</td>
  129. <td class="px-2 py-1">8114</td>
  130. <td class="px-2 py-1">Canada</td>
  131. </tr>
  132. <tr>
  133. <td class="px-2 py-1">Grady King</td>
  134. <td class="px-2 py-1">(344) 638-3562</td>
  135. <td class="px-2 py-1">[email protected]</td>
  136. <td class="px-2 py-1">P.O. Box 257, 4844 Duis St.</td>
  137. <td class="px-2 py-1">Ulster</td>
  138. <td class="px-2 py-1">19766</td>
  139. <td class="px-2 py-1">Belgium</td>
  140. </tr>
  141. <tr>
  142. <td class="px-2 py-1">Dorian Sears</td>
  143. <td class="px-2 py-1">1-811-744-0878</td>
  144. <td class="px-2 py-1">[email protected]</td>
  145. <td class="px-2 py-1">544-2027 Volutpat Ave</td>
  146. <td class="px-2 py-1">Western Cape</td>
  147. <td class="px-2 py-1">16502</td>
  148. <td class="px-2 py-1">Brazil</td>
  149. </tr>
  150. <tr>
  151. <td class="px-2 py-1">Joseph Mejia</td>
  152. <td class="px-2 py-1">(908) 607-5580</td>
  153. <td class="px-2 py-1">[email protected]</td>
  154. <td class="px-2 py-1">6403 Nulla Av.</td>
  155. <td class="px-2 py-1">Kansas</td>
  156. <td class="px-2 py-1">30724</td>
  157. <td class="px-2 py-1">France</td>
  158. </tr>
  159. <tr>
  160. <td class="px-2 py-1">Lesley Walter</td>
  161. <td class="px-2 py-1">1-368-720-4221</td>
  162. <td class="px-2 py-1">[email protected]</td>
  163. <td class="px-2 py-1">Ap #639-9148 Odio. Road</td>
  164. <td class="px-2 py-1">Zhōngnán</td>
  165. <td class="px-2 py-1">36638</td>
  166. <td class="px-2 py-1">Italy</td>
  167. </tr>
  168. <tr>
  169. <td class="px-2 py-1">Mufutau Mack</td>
  170. <td class="px-2 py-1">(282) 276-8465</td>
  171. <td class="px-2 py-1">[email protected]</td>
  172. <td class="px-2 py-1">151 Accumsan Road</td>
  173. <td class="px-2 py-1">Canarias</td>
  174. <td class="px-2 py-1">410816</td>
  175. <td class="px-2 py-1">Canada</td>
  176. </tr>
  177. <tr>
  178. <td class="px-2 py-1">Leah Sosa</td>
  179. <td class="px-2 py-1">1-844-322-1643</td>
  180. <td class="px-2 py-1">[email protected]</td>
  181. <td class="px-2 py-1">Ap #574-8034 Phasellus St.</td>
  182. <td class="px-2 py-1">Central Region</td>
  183. <td class="px-2 py-1">UU0J 8FN</td>
  184. <td class="px-2 py-1">Australia</td>
  185. </tr>
  186. <tr>
  187. <td class="px-2 py-1">Moana Dickson</td>
  188. <td class="px-2 py-1">(951) 105-1941</td>
  189. <td class="px-2 py-1">[email protected]</td>
  190. <td class="px-2 py-1">8059 Montes, St.</td>
  191. <td class="px-2 py-1">North Island</td>
  192. <td class="px-2 py-1">65653-276</td>
  193. <td class="px-2 py-1">Ireland</td>
  194. </tr>
  195. <tr>
  196. <td class="px-2 py-1">Unity Jennings</td>
  197. <td class="px-2 py-1">(720) 168-6976</td>
  198. <td class="px-2 py-1">[email protected]</td>
  199. <td class="px-2 py-1">Ap #562-1244 Est Street</td>
  200. <td class="px-2 py-1">North Island</td>
  201. <td class="px-2 py-1">5558 DT</td>
  202. <td class="px-2 py-1">Brazil</td>
  203. </tr>
  204. <tr>
  205. <td class="px-2 py-1">Kelsey Kennedy</td>
  206. <td class="px-2 py-1">(541) 523-4605</td>
  207. <td class="px-2 py-1">[email protected]</td>
  208. <td class="px-2 py-1">879-8761 Magna. Av.</td>
  209. <td class="px-2 py-1">Free State</td>
  210. <td class="px-2 py-1">192345</td>
  211. <td class="px-2 py-1">Nigeria</td>
  212. </tr>
  213. <tr>
  214. <td class="px-2 py-1">Rajah Mercado</td>
  215. <td class="px-2 py-1">1-355-558-8976</td>
  216. <td class="px-2 py-1">[email protected]</td>
  217. <td class="px-2 py-1">2254 Purus Av.</td>
  218. <td class="px-2 py-1">Tarapacá</td>
  219. <td class="px-2 py-1">47877-808</td>
  220. <td class="px-2 py-1">United Kingdom</td>
  221. </tr>
  222. <tr>
  223. <td class="px-2 py-1">William Mays</td>
  224. <td class="px-2 py-1">(475) 524-6242</td>
  225. <td class="px-2 py-1">[email protected]</td>
  226. <td class="px-2 py-1">P.O. Box 577, 8281 Enim. Ave</td>
  227. <td class="px-2 py-1">West Region</td>
  228. <td class="px-2 py-1">983619</td>
  229. <td class="px-2 py-1">Chile</td>
  230. </tr>
  231. <tr>
  232. <td class="px-2 py-1">Quamar Justice</td>
  233. <td class="px-2 py-1">(538) 814-4350</td>
  234. <td class="px-2 py-1">[email protected]</td>
  235. <td class="px-2 py-1">611-2564 Mollis Av.</td>
  236. <td class="px-2 py-1">Hampshire</td>
  237. <td class="px-2 py-1">393011</td>
  238. <td class="px-2 py-1">Canada</td>
  239. </tr>
  240. <tr>
  241. <td class="px-2 py-1">Quinn Knapp</td>
  242. <td class="px-2 py-1">1-515-500-7118</td>
  243. <td class="px-2 py-1">[email protected]</td>
  244. <td class="px-2 py-1">Ap #486-2817 Sed Av.</td>
  245. <td class="px-2 py-1">Manisa</td>
  246. <td class="px-2 py-1">513128</td>
  247. <td class="px-2 py-1">Turkey</td>
  248. </tr>
  249. <tr>
  250. <td class="px-2 py-1">Calista Rose</td>
  251. <td class="px-2 py-1">(416) 485-7812</td>
  252. <td class="px-2 py-1">[email protected]</td>
  253. <td class="px-2 py-1">Ap #324-8643 Nisi Rd.</td>
  254. <td class="px-2 py-1">Amazonas</td>
  255. <td class="px-2 py-1">840686</td>
  256. <td class="px-2 py-1">New Zealand</td>
  257. </tr>
  258. </tbody>
  259. </table>
  260. </div>
  261. </div>
  262. </div>
  263. </div>
  264. </div>
  265. </main>
  266. <footer class="container-fluid py-3" style="background:#495C83; color:#fff">
  267. <div class="container-fluid my-2">
  268. <div class="text-center">
  269. <b>JavaScript - Table to Excel &copy; 2022</b>
  270. </div>
  271. </div>
  272. </footer>
  273. </body>
  274. <script src="script.js"></script>
  275. </html>

JavaScript

Next, is creating the JavaScript file that contains the script for exporting the table data to .xls and .csv files. This file is loaded at the index.html file and is known as script.js.

  1. /**
  2. * Exporting Table Data into Excel
  3. */
  4.  
  5. document.getElementById("exportTable").addEventListener("click", function(e){
  6.  
  7. e.preventDefault()
  8.  
  9. var _tbl = document.getElementById('exampleTbl').outerHTML
  10.  
  11. var excel_content = `<html><body>${_tbl}</body></html>`
  12.  
  13. var file = new Blob([excel_content], {type:'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'});
  14. var dl_anchor = document.createElement('a')
  15. dl_anchor.style.display = this.nonce;
  16. dl_anchor.download = "tableData.xls";
  17. dl_anchor.href = window.URL.createObjectURL(file);
  18.  
  19. document.body.appendChild(dl_anchor)
  20. dl_anchor.click()
  21.  
  22. })
  23.  
  24. /**
  25. * Exporting Table Data into CSV
  26. */
  27.  
  28. document.getElementById("exportTableCSV").addEventListener("click", function(e){
  29.  
  30. e.preventDefault()
  31.  
  32. var _tbl_rows = document.querySelectorAll('#exampleTbl tr')
  33. var csv ="";
  34. var rows = []
  35. _tbl_rows.forEach(el => {
  36. var row = []
  37. el.querySelectorAll('th, td').forEach(ele => {
  38. var ele_clone = ele.cloneNode(true)
  39. ele_clone.innerText = (ele_clone.innerText).replace(/\"/gi, '\"\"')
  40. ele_clone.innerText = ('"' + ele_clone.innerText + '"')
  41. row.push(ele_clone.innerText)
  42. })
  43. rows.push(row.join(","));
  44. })
  45. csv += rows.join(`\r\n`)
  46. var file = new Blob([csv], {type:'text/csv'});
  47. var dl_anchor = document.createElement('a')
  48. dl_anchor.style.display = this.nonce;
  49. dl_anchor.download = "tableCsv.csv";
  50. dl_anchor.href = window.URL.createObjectURL(file);
  51.  
  52. document.body.appendChild(dl_anchor)
  53. dl_anchor.click()
  54. })

Snapshots

Here are the snapshots of the result of the program source code I provided above.

Page Interface

Exporting Table Data to Excel Demo App

Exported Excel Spreadsheet

Exporting Table Data to Excel Demo App

Exported CSV File

Exporting Table Data to Excel Demo App

There you go! You can now test the sample program on your end and see if it works properly. I provided also the complete source code file of the sample program that I created for this tutorial. You can download it by clicking the download button below this article.

That's it! That's the end of this tutorial. I hope this Exporting HTML Table to Excel Spreadsheet and CSV File using JavaScript Tutorial will help you with what you are looking for and you'll find this useful for your current and future projects.

Explore more on this website for more Tutorials and Free Source Codes.

Happy Coding :)

Comments

Submitted byAnonymous (not verified)on Fri, 12/23/2022 - 18:42

good work

Add new comment