我正在导入一个包含大量发票数据的csv文件。 此数据需要根据供应商 ID 分组在一起,以显示每个供应商的标题以及该供应商 ID 的所有发票的总和;然后在其下方显示每张单独的发票。 该项目的目标是导入 CSV,向用户显示数据,允许通过选择框更改某些值,然后单击按钮导出为 XML。 XML 的结构与 HTML 类似,其中每组发票首先显示某些通用数据,然后汇款数据如下所示。为了实现这一点,我正在尝试以一种帮助我使用此 http://goessner.net/download/prj/jsonxml/将其正确转换为XML的方式构建对象。
问题:后两笔付款需要分组在一起,我希望为每行详细数据创建一个数组,然后将其添加到主对象到 PmtDetail 属性中。目前,此代码仅广告第一行,而忽略其余部分。
CSV 代码段(我不包括此处代码中使用的所有行)
ID CardCode payment_sum amount
1610165 BENV5271 100 100
1609026 BENV5635 509.85 287.33
1609025 BENV5635 509.85 222.52
杰伦
[{"DocNum":"1610165","CardCode":"BENV5271","InvPayAmnt":"100.00","PmntDate":"2012-03-29","payment_sum":"100.00"},
{"DocNum":"1609026","CardCode":"BENV5635","InvPayAmnt":"287.33","PmntDate":"2012-03-29","payment_sum":"509.85"},
{"DocNum":"1609025","CardCode":"BENV5635","InvPayAmnt":"222.52","PmntDate":"2012-03-29","payment_sum":"509.85"}]
Jquery
$(document).ready(function() {
$.getJSON('CSV.php', function(data) {
var prevCardCode = '';
var newDiv; var NewDiv2;
var PaymentFormat;
$.each(data, function(index, element) { //looping once to display header info such as sum
XMLObject = []; // Creating a new object for each row
if (element['CardCode'] != prevCardCode) {
XMLObject.Vendor_Sum = element['payment_sum'];
XMLObject.Name1 = element['CardName'];
XMLObject.Addr1 = element['Address'];
console.log(XMLObject);
newDiv = $('<div/>').addClass('row').appendTo('#showdata');
$('<div class="sum_field">' + 'Total: ' + element['payment_sum'] + '</div>').appendTo(newDiv);
$('<div class="options">Payment Format: <select name="Payment_Format" id="Payment_Format"><option value="CTX" selected="selected">Company to Company</option><option value="PPD">Company to Person</option></select> </div><div id="Selected_Format"></div>').appendTo(newDiv);
XMLObject.paymentFormat = $('select#Payment_Format').val();;
$('select#Payment_Format').change(function(){
PaymentFormat = $(this).val();
XMLObject.paymentFormat = PaymentFormat;
});
}
newDiv2 = $('<div/>').addClass('sub_row').appendTo(newDiv);
prevCardCode = element['CardCode'];
$.each(element, function(key, value) { looping 2nd time to display the detail info
XMLObjectDetail = {}; // Creating an array for each row of detail info
XMLObjectDetail['TotalCurAmount'] = element['InvPayAmnt'];
XMLObjectDetail['NetCurAmount'] = element['InvPayAmnt'];
$('<div class="field">' + value + '</div>').appendTo(newDiv2);
XMLObject.PmtDetail = XMLObjectDetail;
});
});
});
});
.PHP
<?php
if (($handle = fopen('upload/BEN-new.csv', "r")) === FALSE) {
die('Error opening file');
}
$headers = fgetcsv($handle, 1024, ',');
$complete = array();
while ($row = fgetcsv($handle, 1024, ",")) {
$complete[] = array_combine($headers, $row);
}
fclose($handle);
echo json_encode($complete);
?>
一些想法:
-
$.each(data, ... //looping once to display header info such as sum
您不会在任何地方创建总和。此外,这是遍历所有data
行的唯一循环。 -
XMLObject = []; // Creating a new object for each row
- 不,您正在创建一个数组。你真的应该创建一个对象({}
),因为你把它作为一个对象。 -
XMLObject =...
.您在这里缺少var
关键字。每次迭代都会创建一个新对象,但将每个对象分配给同一个全局变量。这就是为什么#Payment_Format
更改处理程序只会更改上次创建的对象(当前由"XMLObject
"引用的对象)的格式的原因。 -
$('...<select name="Payment_Format" id="Payment_Format">...')
每次迭代都会创建一个带有 id 的选择。您认为该ID将如何是唯一的?这也是为什么('select#Payment_Format')
不会选择在当前迭代中创建的元素的原因。 -
$.each(element... looping 2nd time to display the detail info
否这不是第二个循环,而是一个循环,它将遍历当前element
的属性 - 循环将应用于每个迭代的data
行。 -
XMLObjectDetail = {}; // Creating an array for each row of detail info
- 不,您正在创建一个对象。同样,您缺少var
关键字。 - (编辑)
XMLObject.PmtDetail = XMLObjectDetail;
- 您在此处覆盖元素的每次迭代的"PmtDetail"属性。这不应该是您附加到的数组吗? - 在循环代码的末尾,您有一个
XMLObject
,其中包含有关当前行的数据。难道你不想用它做点什么,例如把它推到一个行对象数组上吗?
好的,我想现在我得到了你想要实现的目标。适当的结构可能是:
[ {
"CardCode":"BENV5271"
"details": [ {
"DocNum": "1610165",
"InvPayAmnt": "100.00",
"PmntDate": "2012-03-29"
} ],
"payment_sum": "100.00"
}, {
"CardCode": "BENV5635",
"details": [ {
"DocNum": "1609026"
"InvPayAmnt": "287.33",
"PmntDate": "2012-03-29"
}, {
"DocNum": "1609025",
"InvPayAmnt": "222.52",
"PmntDate": "2012-03-29"
} ],
"payment_sum": "509.85"
} ]
或相同,就像 id 的对象(键值映射)一样:
{
"BENV5271" : {
"details": {
"1610165": {
"InvPayAmnt": "100.00",
"PmntDate": "2012-03-29"
}
}
"payment_sum": "100.00"
},
"BENV5635": {
"details": {
"1609026": {
"InvPayAmnt": "287.33",
"PmntDate": "2012-03-29"
},
"1609025": {
"InvPayAmnt": "222.52",
"PmntDate": "2012-03-29"
}
},
"payment_sum": "509.85"
}
}
您也可以使用 JSON 的数字类型作为数字值,而不是字符串 :-)您应该立即从数据库中创建该结构。如您所见,CSV不是它的最佳表示形式,并且由于JSON和XML能够表示它,因此您不应该使用SQL->CSV->JSON(table)->JSON(structured)->XML,而是SQL->JSON(结构化)->XML甚至更好的立即SQL->XML。您可以使用 Ajax 轻松读取 XML,并在 JavaScript 中更改其 DOM。
如果你真的需要从格式错误的对象重组到JS中的漂亮结构,那么代码就是这样:
var cards = {}; // an object indexed by the CardCodes;
for (var i=0; i<data.length; i++) { // loop through the received JSON
// data[i] equals the "element" variable from your code
var code = data[i].CardCode;
if (! code in cards) { // there is no card with that code
cards[code] = {
vendorSum: data[i].payment_sum,
name: data[i].CardName,
addr: data[i].Address,
...
pmtDetail: [] // create array for the details
};
} // else: element already created
cards[code].pmtDetail.push({
docNum: data[i].DocNum,
amount: data[i].InvPayAmnt
...
}); // adds a new detail object to the array
}
我使用 php 用对象/数组构建了 CVS:
while ($row = fgetcsv($handle, 1024, ",")) {
$cardCodes[] = array_combine($headers, $row);
}
foreach ($cardCodes as $key => $value) {
$payments[$value['ggg']]['aaa']['xxx'] = 'element['gggg']';
}
echo json_encode($payments);
然后使用 JS 读取此数据。