如何从html表单中输入值并转换为csv?



所以我想从HTML输入表单采取一对值,基本上能够生成一个csv文件下载的用户,当他们点击一个按钮,这将包括他们输入到表单的数据。然而,我对如何去做这件事感到困惑,在网上找不到一个好的指南。

我也想自定义csv格式将如何,如果可能的话,希望以某种方式知道我想做什么!谢谢。

编辑:我不要求在html中这样做,我认为javascript是最好的选择

我的HTML代码

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>UniWeighter</title>
<link rel="icon" href="images/icon.ico">
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.2/css/bulma.min.css"/>
<script
src="https://use.fontawesome.com/releases/v5.3.1/js/all.js">
</script>
</head>
<body>
<style>
body {
background-image: url("images/background.png");
}
</style>
<section class="section">
<div class="container is-centered is-mobile">
<div class="content has-text-centered">
<h1><b>UniWeighter</b></h1>
<h2>Weighted Average Grade Calculator</h2>
<hr>
<div class="box">
<p>
This Simple Grade Calculator will determine your average grade for your assignments,
end of year grade or end of university grade.
<br>
The weighted average simply takes into account how much each course is worth when calculating the average.
<br>
This calculator can also be used to calculate any weighted average, not just courses.
<br>
</p>
</div>

<div class="column is-two-quarter is is-offset-two-quarter is-mobile">
<div class="box">
<article class="media">
<div class="media-left">
<figure class="image is-64x64">
<img src="images/help.png" alt="Image">
</figure>
</div>
<div class="media-content">
<div class="content">
<p>
<strong>How does it actually work?</strong> <small>Just one example below</small>
<br>
Lets say you want to find a end of module final mark. You have 2 total exams/assignments for that module.
One worth <b>40%</b> weighting and you get <b>75/100</b> marks, the other worth <b>60%</b> weighting and you get <b>62/100</b>.
So you can type in 40 for the weight and 75 for the grade on first row, also 60 and 62 for the next row.
Press Calculate and you find you got an overall average mark of <b>67.2</b> and a grade of <b>2:1</b> for that module.
</p>
</div>
</div>
</article>
</div>
</div>
</div>
<div class="columns is-centered">
<div class="column is-three-quarters">
<div class="card">
<br>
<div class="columns is-gapless is-multiline is-mobile">
<div class="column is-one-third has-text-centered is-size-5">
<h1 class="has-text-weight-semibold">The Entry</h1>
</div>
<div class="column is-one-third has-text-centered is-size-5">
<h1 class="has-text-weight-semibold">Grade (%)</h1>
</div>
<div class="column is-one-third has-text-centered is-size-5">
<h1 class="has-text-weight-semibold">Weight (Credits)</h1>
</div>
</div>
<div class="card-content">
<form id="grade-form">
<div class="level">
<!-- Left side -->
<div class="level-left is-marginless">
<div class="level-item">
<p class="number">1</p>
Assignment/Module
</div>
</div>
<!-- Right side -->
<div class="level-right">
<div class="level-item">
<div class="field">
<div class="control has-icons-right ">
<input class="input" id="grade1" type="number" />
<span class="icon is-small is-right">
<i class="fa fa-percentage"></i>
</span>
</div>
</div>
</div>
</div>
<div class="level-right">
<div class="level-item">
<div class="field">
<div class="control has-icons-left ">
<input class="input" id="credit1" type="number" />
<span class="icon is-small is-left">
<i class="fas fa-coins"></i>
</span>
</div>
</div>
</div>
</div>
</div>
<div class="level">
<!-- Left side -->
<div class="level-left is-marginless">
<div class="level-item">
<p class="number">2</p>
Assignment/Module
</div>
</div>
<!-- Right side -->
<div class="level-right">
<div class="level-item">
<div class="field">
<div class="control has-icons-right">
<input class="input" id="grade2" type="number" />
<span class="icon is-small is-right">
<i class="fa fa-percentage"></i>
</span>
</div>
</div>
</div>
</div>
<div class="level-right">
<div class="level-item">
<div class="field">
<div class="control has-icons-left ">
<input class="input" id="credit2" type="number" />
<span class="icon is-small is-left">
<i class="fas fa-coins"></i>
</span>
</div>
</div>
</div>
</div>
</div>
<div class="level">
<!-- Left side -->
<div class="level-left is-marginless">
<div class="level-item">
<p class="number">3</p>
Assignment/Module
</div>
</div>
<!-- Right side -->
<div class="level-right">
<div class="level-item">
<div class="field">
<div class="control has-icons-right">
<input class="input" id="grade3" type="number" />
<span class="icon is-small is-right">
<i class="fa fa-percentage"></i>
</span>
</div>
</div>
</div>
</div>
<div class="level-right">
<div class="level-item">
<div class="field">
<div class="control has-icons-left ">
<input class="input" id="credit3" type="number" />
<span class="icon is-small is-left">
<i class="fas fa-coins"></i>
</span>
</div>
</div>
</div>
</div>
</div>
<div class="level">
<!-- Left side -->
<div class="level-left is-marginless">
<div class="level-item">
<p class="number">4</p>
Assignment/Module
</div>
</div>
<!-- Right side -->
<div class="level-right">
<div class="level-item">
<div class="field">
<div class="control has-icons-right">
<input class="input" id="grade4" type="number" />
<span class="icon is-small is-right">
<i class="fa fa-percentage"></i>
</span>
</div>
</div>
</div>
</div>
<div class="level-right">
<div class="level-item">
<div class="field">
<div class="control has-icons-left ">
<input class="input" id="credit4" type="number" />
<span class="icon is-small is-left">
<i class="fas fa-coins"></i>
</span>
</div>
</div>
</div>
</div>
</div>
<div class="level">
<!-- Left side -->
<div class="level-left is-marginless">
<div class="level-item">
<p class="number">5</p>
Assignment/Module
</div>
</div>
<!-- Right side -->
<div class="level-right">
<div class="level-item">
<div class="field">
<div class="control has-icons-right">
<input class="input" id="grade5" type="number" />
<span class="icon is-small is-right">
<i class="fa fa-percentage"></i>
</span>
</div>
</div>
</div>
</div>
<div class="level-right">
<div class="level-item">
<div class="field">
<div class="control has-icons-left ">
<input class="input" id="credit5" type="number" />
<span class="icon is-small is-left">
<i class="fas fa-coins"></i>
</span>
</div>
</div>
</div>
</div>
</div>
<div class="level">
<!-- Left side -->
<div class="level-left is-marginless">
<div class="level-item">
<p class="number">6</p>
Assignment/Module
</div>
</div>
<!-- Right side -->
<div class="level-right">
<div class="level-item">
<div class="field">
<div class="control has-icons-right">
<input class="input" id="grade6" type="number" />
<span class="icon is-small is-right">
<i class="fa fa-percentage"></i>
</span>
</div>
</div>
</div>
</div>
<div class="level-right">
<div class="level-item">
<div class="field">
<div class="control has-icons-left ">
<input class="input" id="credit6" type="number" />
<span class="icon is-small is-left">
<i class="fas fa-coins"></i>
</span>
</div>
</div>
</div>
</div>
</div>
<div class="level">
<!-- Left side -->
<div class="level-left is-marginless">
<div class="level-item">
<p class="number">7</p>
Assignment/Module
</div>
</div>
<!-- Right side -->
<div class="level-right">
<div class="level-item">
<div class="field">
<div class="control has-icons-right">
<input class="input" id="grade7" type="number" />
<span class="icon is-small is-right">
<i class="fa fa-percentage"></i>
</span>
</div>
</div>
</div>
</div>
<div class="level-right">
<div class="level-item">
<div class="field">
<div class="control has-icons-left ">
<input class="input" id="credit7" type="number" />
<span class="icon is-small is-left">
<i class="fas fa-coins"></i>
</span>
</div>
</div>
</div>
</div>
</div>
<div class="control">
<button id="submit" class="button is-large is-fullwidth is-primary is-outlined">
Calculate
</button>
</div>
<div class="control">
<button id="download" class="button is-large is-fullwidth is-primary is-outlined">
Get CSV file of data
</button>
</div>
</form>
</div>
</div>
</div>

</div>
</div>
</section>
<!-- RESULTS -->
<section class="section is-centered is-mobile is-paddingless"> 
<h1 class="title has-text-centered">Calculated Results</h1>
<div class="columns is-multiline is-centered">

<div class="column is-12-tablet is-6-desktop is-3-widescreen ">
<div class="notification is-success is-light has-text">
<p id="averageGrade" class="title is-1"><i class="fa fa-percentage"></i></p>
<p class="subtitle is-4">Average Grade</p>
</div>
</div>
<div class="column is-12-tablet is-6-desktop is-3-widescreen">
<div class="notification is-link is-light has-text">
<p id="formalGrade" class="title is-1"><i class="fas fa-graduation-cap"></i></p>
<p class="subtitle is-4">Formal Grade</p>
</div>
</div>
</div>
</section>
<br>
<div class="line" style="padding: 1%;">
<hr>
</div>

<footer class="footer">
<div class="content has-text-centered">
<p>
<br><br>
<strong>UniWeighter</strong> by <a href="https://mathewsjoy.herokuapp.com/">Mathews Joy</a>. The source code is licensed
<a href="http://opensource.org/licenses/mit-license.php">MIT</a>. <strong>Share -</strong> 
<a href="https://twitter.com/intent/tweet?text=https%3A//uniweighter.netlify.app/" aria-label="reply">
<span class="icon is-small">
<i class="fab fa-twitter-square" aria-hidden="true"></i>
</span>
</a>
<a href="https://www.facebook.com/sharer/sharer.php?u=https%3A//uniweighter.netlify.app/" aria-label="retweet">
<span class="icon is-small">
<i class="fab fa-facebook" aria-hidden="true"></i>
</span>
</a>
<a href="https://www.linkedin.com/shareArticle?mini=true&url=https%3A//uniweighter.netlify.app/&title=Checkout%20Uniweighter!&summary=&source=" aria-label="like">
<span class="icon is-small">
<i class="fab fa-linkedin" aria-hidden="true"></i>
</span>
</a>
</div>
</nav>
</p>
</div>
</footer>

</body>
<script src="index.js"></script>
</html>

document.querySelector("#download").addEventListener('click', generateCSV);

function generateCSV(e){
e.preventDefault();
const formdata = new FormData(document.getElementById('grade-form'));
const formObj = Object.fromEntries(formdata);
const len = Object.keys(formObj).length/2;
let formValues = '';
for(let i=1; i<= len; i++){
// comma separated values and break line
formValues += formObj['grade'+i] +','+formObj['credit'+i]+ "rn";
}
downloadCSV(formValues);
}

function downloadCSV(formValues){
const columnNames = "Grade (%), Weight (Credits)";
let csvContent = "data:text/csv;charset=utf-8,";
csvContent += columnNames + "rn";
csvContent += formValues + "rn";
const encodedUri = encodeURI(csvContent);
var link = document.createElement("a");
link.setAttribute("href", encodedUri);
link.setAttribute("download", "my-form-data.csv");
document.body.appendChild(link);
link.click();
// link.remove();
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>UniWeighter</title>
<link rel="icon" href="images/icon.ico">
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.2/css/bulma.min.css"/>
<script
src="https://use.fontawesome.com/releases/v5.3.1/js/all.js">
</script>
</head>
<body>
<style>
body {
background-image: url("images/background.png");
}
</style>
<section class="section">
<div class="container is-centered is-mobile">
<div class="content has-text-centered">
<h1><b>UniWeighter</b></h1>
<h2>Weighted Average Grade Calculator</h2>
<hr>
<div class="box">
<p>
This Simple Grade Calculator will determine your average grade for your assignments,
end of year grade or end of university grade.
<br>
The weighted average simply takes into account how much each course is worth when calculating the average.
<br>
This calculator can also be used to calculate any weighted average, not just courses.
<br>
</p>
</div>

<div class="column is-two-quarter is is-offset-two-quarter is-mobile">
<div class="box">
<article class="media">
<div class="media-left">
<figure class="image is-64x64">
<img src="images/help.png" alt="Image">
</figure>
</div>
<div class="media-content">
<div class="content">
<p>
<strong>How does it actually work?</strong> <small>Just one example below</small>
<br>
Lets say you want to find a end of module final mark. You have 2 total exams/assignments for that module.
One worth <b>40%</b> weighting and you get <b>75/100</b> marks, the other worth <b>60%</b> weighting and you get <b>62/100</b>.
So you can type in 40 for the weight and 75 for the grade on first row, also 60 and 62 for the next row.
Press Calculate and you find you got an overall average mark of <b>67.2</b> and a grade of <b>2:1</b> for that module.
</p>
</div>
</div>
</article>
</div>
</div>
</div>
<div class="columns is-centered">
<div class="column is-three-quarters">
<div class="card">
<br>
<div class="columns is-gapless is-multiline is-mobile">
<div class="column is-one-third has-text-centered is-size-5">
<h1 class="has-text-weight-semibold">The Entry</h1>
</div>
<div class="column is-one-third has-text-centered is-size-5">
<h1 class="has-text-weight-semibold">Grade (%)</h1>
</div>
<div class="column is-one-third has-text-centered is-size-5">
<h1 class="has-text-weight-semibold">Weight (Credits)</h1>
</div>
</div>
<div class="card-content">

<form id="grade-form">
<div class="level">
<!-- Left side -->
<div class="level-left is-marginless">
<div class="level-item">
<p class="number">1</p>
Assignment/Module
</div>
</div>
<!-- Right side -->
<div class="level-right">
<div class="level-item">
<div class="field">
<div class="control has-icons-right ">
<input class="input" name="grade1" id="grade1" type="number" />
<span class="icon is-small is-right">
<i class="fa fa-percentage"></i>
</span>
</div>
</div>
</div>
</div>
<div class="level-right">
<div class="level-item">
<div class="field">
<div class="control has-icons-left ">
<input class="input" name="credit1" id="credit1" type="number" />
<span class="icon is-small is-left">
<i class="fas fa-coins"></i>
</span>
</div>
</div>
</div>
</div>
</div>
<div class="level">
<!-- Left side -->
<div class="level-left is-marginless">
<div class="level-item">
<p class="number">2</p>
Assignment/Module
</div>
</div>
<!-- Right side -->
<div class="level-right">
<div class="level-item">
<div class="field">
<div class="control has-icons-right">
<input class="input" name="grade2" id="grade2" type="number" />
<span class="icon is-small is-right">
<i class="fa fa-percentage"></i>
</span>
</div>
</div>
</div>
</div>
<div class="level-right">
<div class="level-item">
<div class="field">
<div class="control has-icons-left ">
<input class="input" name="credit2" id="credit2" type="number" />
<span class="icon is-small is-left">
<i class="fas fa-coins"></i>
</span>
</div>
</div>
</div>
</div>
</div>
<div class="level">
<!-- Left side -->
<div class="level-left is-marginless">
<div class="level-item">
<p class="number">3</p>
Assignment/Module
</div>
</div>
<!-- Right side -->
<div class="level-right">
<div class="level-item">
<div class="field">
<div class="control has-icons-right">
<input class="input" name="grade3" id="grade3" type="number" />
<span class="icon is-small is-right">
<i class="fa fa-percentage"></i>
</span>
</div>
</div>
</div>
</div>
<div class="level-right">
<div class="level-item">
<div class="field">
<div class="control has-icons-left ">
<input class="input" name="credit3" id="credit3" type="number" />
<span class="icon is-small is-left">
<i class="fas fa-coins"></i>
</span>
</div>
</div>
</div>
</div>
</div>
<div class="level">
<!-- Left side -->
<div class="level-left is-marginless">
<div class="level-item">
<p class="number">4</p>
Assignment/Module
</div>
</div>
<!-- Right side -->
<div class="level-right">
<div class="level-item">
<div class="field">
<div class="control has-icons-right">
<input class="input" name="grade4" id="grade4" type="number" />
<span class="icon is-small is-right">
<i class="fa fa-percentage"></i>
</span>
</div>
</div>
</div>
</div>
<div class="level-right">
<div class="level-item">
<div class="field">
<div class="control has-icons-left ">
<input class="input" name="credit4" id="credit4" type="number" />
<span class="icon is-small is-left">
<i class="fas fa-coins"></i>
</span>
</div>
</div>
</div>
</div>
</div>
<div class="level">
<!-- Left side -->
<div class="level-left is-marginless">
<div class="level-item">
<p class="number">5</p>
Assignment/Module
</div>
</div>
<!-- Right side -->
<div class="level-right">
<div class="level-item">
<div class="field">
<div class="control has-icons-right">
<input class="input" name="grade5" id="grade5" type="number" />
<span class="icon is-small is-right">
<i class="fa fa-percentage"></i>
</span>
</div>
</div>
</div>
</div>
<div class="level-right">
<div class="level-item">
<div class="field">
<div class="control has-icons-left ">
<input class="input" name="credit5" id="credit5" type="number" />
<span class="icon is-small is-left">
<i class="fas fa-coins"></i>
</span>
</div>
</div>
</div>
</div>
</div>
<div class="level">
<!-- Left side -->
<div class="level-left is-marginless">
<div class="level-item">
<p class="number">6</p>
Assignment/Module
</div>
</div>
<!-- Right side -->
<div class="level-right">
<div class="level-item">
<div class="field">
<div class="control has-icons-right">
<input class="input" name="grade6" id="grade6" type="number" />
<span class="icon is-small is-right">
<i class="fa fa-percentage"></i>
</span>
</div>
</div>
</div>
</div>
<div class="level-right">
<div class="level-item">
<div class="field">
<div class="control has-icons-left ">
<input class="input" name="credit6" id="credit6" type="number" />
<span class="icon is-small is-left">
<i class="fas fa-coins"></i>
</span>
</div>
</div>
</div>
</div>
</div>
<div class="level">
<!-- Left side -->
<div class="level-left is-marginless">
<div class="level-item">
<p class="number">7</p>
Assignment/Module
</div>
</div>
<!-- Right side -->
<div class="level-right">
<div class="level-item">
<div class="field">
<div class="control has-icons-right">
<input class="input" name="grade7" id="grade7" type="number" />
<span class="icon is-small is-right">
<i class="fa fa-percentage"></i>
</span>
</div>
</div>
</div>
</div>
<div class="level-right">
<div class="level-item">
<div class="field">
<div class="control has-icons-left ">
<input class="input" name="credit7" id="credit7" type="number" />
<span class="icon is-small is-left">
<i class="fas fa-coins"></i>
</span>
</div>
</div>
</div>
</div>
</div>
<div class="control">
<button id="submit" class="button is-large is-fullwidth is-primary is-outlined">
Calculate
</button>
</div>
<div class="control">
<button id="download" class="button is-large is-fullwidth is-primary is-outlined">
Get CSV file of data
</button>
</div>
</form>
</div>
</div>
</div>

</div>
</div>
</section>
<!-- RESULTS -->
<section class="section is-centered is-mobile is-paddingless"> 
<h1 class="title has-text-centered">Calculated Results</h1>
<div class="columns is-multiline is-centered">

<div class="column is-12-tablet is-6-desktop is-3-widescreen ">
<div class="notification is-success is-light has-text">
<p id="averageGrade" class="title is-1"><i class="fa fa-percentage"></i></p>
<p class="subtitle is-4">Average Grade</p>
</div>
</div>
<div class="column is-12-tablet is-6-desktop is-3-widescreen">
<div class="notification is-link is-light has-text">
<p id="formalGrade" class="title is-1"><i class="fas fa-graduation-cap"></i></p>
<p class="subtitle is-4">Formal Grade</p>
</div>
</div>
</div>
</section>
<br>
<div class="line" style="padding: 1%;">
<hr>
</div>

<footer class="footer">
<div class="content has-text-centered">
<p>
<br><br>
<strong>UniWeighter</strong> by <a href="https://mathewsjoy.herokuapp.com/">Mathews Joy</a>. The source code is licensed
<a href="http://opensource.org/licenses/mit-license.php">MIT</a>. <strong>Share -</strong> 
<a href="https://twitter.com/intent/tweet?text=https%3A//uniweighter.netlify.app/" aria-label="reply">
<span class="icon is-small">
<i class="fab fa-twitter-square" aria-hidden="true"></i>
</span>
</a>
<a href="https://www.facebook.com/sharer/sharer.php?u=https%3A//uniweighter.netlify.app/" aria-label="retweet">
<span class="icon is-small">
<i class="fab fa-facebook" aria-hidden="true"></i>
</span>
</a>
<a href="https://www.linkedin.com/shareArticle?mini=true&url=https%3A//uniweighter.netlify.app/&title=Checkout%20Uniweighter!&summary=&source=" aria-label="like">
<span class="icon is-small">
<i class="fab fa-linkedin" aria-hidden="true"></i>
</span>
</a>
</div>
</nav>
</p>
</div>
</footer>
</body>
<!--<script src="index.js"></script>-->
</html>

将所有输入名称作为columnname,并将其作为第一行(列名)附加到csv内容

const columnNames = Object.keys(formObj).map(key => key.toUpperCase()).join(",");
let csvContent = "data:text/csv;charset=utf-8,";
csvContent += columnNames + "rn";

删除所有表单值,并将其附加到csv内容。

假设用户输入的地址值为New Braunfels, TX, 78130由于逗号分隔,因此该CSV将创建3个列条目New BraunfelsTX78130。为了解决这个问题,我们将,替换为,这样它将在一个列中添加

const formValues = Object.values(formObj).map(val => val.replaceAll(',', ' ')).join(",");
csvContent += formValues + "rn";

function downloadCSV(){
const formEl = document.forms.userForm;
const formData = new FormData(formEl);
const formObj = Object.fromEntries(formData);
const columnNames = Object.keys(formObj).map(key => key.toUpperCase()).join(",");
let csvContent = "data:text/csv;charset=utf-8,";
csvContent += columnNames + "rn";
const formValues = Object.values(formObj).map(val => val.replaceAll(',', ' ')).join(",");
csvContent += formValues + "rn";
// Set encoded csvContent as `href` attribute and also set download attribute to set the file name
const encodedUri = encodeURI(csvContent);
const link = document.querySelector("#downloadRef");
link.setAttribute("href", encodedUri);
link.setAttribute("download", "my-form-data.csv");
}
<form id="userForm">
<div><label>Name<input type="text" name="name"></label></div>
<div><label>Age<input type="number" name="age"></label></div>
<div>
Gender
<label>Male<input type="radio" name="gender" value="male"></label>
<label>Female<input type="radio" name="gender" value="female"></label>
</div>
<div><label>Address<textarea name="address"></textarea></label></div>
<button onclick="downloadCSV()">
<a id="downloadRef"style="text-decoration:none" href="#">Create CSV</a>
</button>
</form>

csvContent设置为href属性后,点击事件将由事件捕获处理

*这段代码不会在这里下载CSV文件,在您的主机上运行代码