数据格式自动转换为父子格式

这是一个excel表单,每行只填充一个列。 (说明:所有城市类别属于V21,所有手机类别属于CityJ等)

V21 CITYR CITYJ HandsetS HandsetHW HandsetHA LOWER_AGE<=20 LOWER_AGE>20 SMS_COUNT<=0 RECHARGE_MRP<=122 RECHARGE_MRP>122 SMS_COUNT>0 

我需要将此格式更改为具有父级和子级分类格式的双列格式。 因此输出表将是

  V21 CITYR V21 CITYJ CITYJ HandsetS CITYJ HandsetHW CITYJ HandsetHA HandsetHA LOWER_AGE<=20 HandsetHA LOWER_AGE>20 LOWER_AGE>20 SMS_COUNT<=0 SMS_COUNT<=0 RECHARGE_MRP<=122 SMS_COUNT<=0 RECHARGE_MRP>122 LOWER_AGE>20 SMS_COUNT>0 

数据是巨大的,所以我不能做手动。 我怎么能自动化这个?

有三个部分的任务,所以我想知道你在问什么是帮助。

  1. 将Excel工作表数据读入Java
  2. 操纵数据
  3. 将数据写回Excel表格。

您曾经说过,数据表很大,不能作为一个整体进入内存。 我能问你有多less顶级元素? 即,你有多less个V21? 如果只有一个,那么你有多less个CITYR / CITYJ?

从我以前的答案中添加一些关于如何操纵数据的源代码。 我给了它一个由制表符分隔的input文件(4个空格等于你在Excel中的一列),下面的代码整齐地打印出来的东西。 请注意,级别== 1的条件为空。 如果你觉得你的JVM有太多的对象,那么你可以在这个地方清除条目和堆栈:)

 package com.ekanathk; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Stack; import java.util.logging.Logger; import org.junit.Test; class Entry { private String input; private int level; public Entry(String input, int level) { this.input = input; this.level = level; } public String getInput() { return input; } public int getLevel() { return level; } @Override public String toString() { return "Entry [input=" + input + ", level=" + level + "]"; } } public class Tester { private static final Logger logger = Logger.getLogger(Tester.class.getName()); @SuppressWarnings("unchecked") @Test public void testSomething() throws Exception { InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("samplecsv.txt"); BufferedReader b = new BufferedReader(new InputStreamReader(is)); String input = null; List entries = new ArrayList(); Stack<Entry> stack = new Stack<Entry>(); stack.push(new Entry("ROOT", -1)); while((input = b.readLine()) != null){ int level = whatIsTheLevel(input); input = input.trim(); logger.info("input = " + input + " at level " + level); Entry entry = new Entry(input, level); if(level == 1) { //periodically clear out the map and write it to another excel sheet } if (stack.peek().getLevel() == entry.getLevel()) { stack.pop(); } Entry parent = stack.peek(); logger.info("parent = " + parent); entries.add(new String[]{parent.getInput(), entry.getInput()}); stack.push(entry); } for(Object entry : entries) { System.out.println(Arrays.toString((String[])entry)); } } private int whatIsTheLevel(String input) { int numberOfSpaces = 0; for(int i = 0 ; i < input.length(); i++) { if(input.charAt(i) != ' ') { return numberOfSpaces/4; } else { numberOfSpaces++; } } return numberOfSpaces/4; } } 

这认为你有一个足够小的文件以适应计算机内存。 即使10MB的文件应该是好的。

它有2个部分:

DataTransformer完成所有需要的数据转换

TreeNode是自定义简单的Tree数据结构

 public class DataTransformer { public static void main(String[] args) throws IOException { InputStream in = DataTransformer.class .getResourceAsStream("source_data.tab"); BufferedReader br = new BufferedReader( new InputStreamReader(in)); String line; TreeNode root = new TreeNode("ROOT", Integer.MIN_VALUE); TreeNode currentNode = root; while ((line = br.readLine()) != null) { int level = getLevel(line); String value = line.trim(); TreeNode nextNode = new TreeNode(value, level); relateNextNode(currentNode, nextNode); currentNode = nextNode; } printAll(root); } public static int getLevel(String line) { final char TAB = '\t'; int numberOfTabs = 0; for (int i = 0; i < line.length(); i++) { if (line.charAt(i) != TAB) { break; } numberOfTabs++; } return numberOfTabs; } public static void relateNextNode( TreeNode currentNode, TreeNode nextNode) { if (currentNode.getLevel() < nextNode.getLevel()) { currentNode.addChild(nextNode); } else { relateNextNode(currentNode.getParent(), nextNode); } } public static void printAll(TreeNode node) { if (!node.isRoot() && !node.getParent().isRoot()) { System.out.println(node); } for (TreeNode childNode : node.getChildren()) { printAll(childNode); } } } class TreeNode implements Serializable { private static final long serialVersionUID = 1L; private TreeNode parent; private List<TreeNode> children = new ArrayList<TreeNode>(); private String value; private int level; public TreeNode(String value, int level) { this.value = value; this.level = level; } public void addChild(TreeNode child) { child.parent = this; this.children.add(child); } public void addSibbling(TreeNode sibbling) { TreeNode parent = this.parent; parent.addChild(sibbling); } public TreeNode getParent() { return parent; } public List<TreeNode> getChildren() { return children; } public String getValue() { return value; } public int getLevel() { return level; } public boolean isRoot() { return this.parent == null; } public String toString() { String str; if (this.parent != null) { str = this.parent.value + '\t' + this.value; } else { str = this.value; } return str; } }