Hi I am trying to convert oracle jdbc resultset to csv file. Below is the code used. Issue occures when there is value like below in the field. It deforms the output csv and all this come in separate line rather than in one field.
Value in Field comes in csv as
[<333message:Runtime error in script' ProcessItem: ' Type: 'ITEM'" 1:0).Internal Script error: java.lang.NullPointerException
Script (line 1):
setHours = 0 ;
if(ts.instanceId == null)
" 3 : ts.instanceId = 0 ;"
Step >]
int ncols = result.getMetaData().getColumnCount();
System.out.println("ColumnCout"+ncols);
FileOutputStream fos=new FileOutputStream(new File("C:\\test.csv"),false);
Writer out = new OutputStreamWriter(new BufferedOutputStream(fos),"UTF_8");
for (int j=1; j<(ncols+1); j++) {
out.append(result.getMetaData().getColumnName (j));
if (j<ncols) out.append(","); else out.append("\r\n");
}
int m =1;
while (result.next()) {
for (int k=1; k<(ncols+1); k++) {
out.append(result.getString(k));
if (k<ncols) out.append(","); else out.append("\r\n");
}
//System.out.println("No of rows"+m);
m++;
}
Are you using "java.sql.ResultSet" class?
If yes, see the library in this link http://opencsv.sourceforge.net/
See an example:
CSVWriter csvWriter = new CSVWriter(new FileWriter("yourfile.csv"), '\t');
java.sql.ResultSet myResultSet = .... ;
csvWriter.writeAll(myResultSet, includeHeaders);
Get the value for the column that could have new lines as
String multiLine = null;
if (k == <col_index> && (mutiLine = rs.getString(k)) != null)
out.append(multiLine.replaceAll("\\n", ""));
else
out.append(result.getString(k));
You could filter all the columns as well but then would incur some performance hit.
Related
I am trying to split , (Comma) delimiter file where I need to skip , (Comma) at position three and rest of , (Comma) I can split.
My code:
String st;
BufferedReader Br = null;
FileOutputStream outFile1 = new FileOutputStream(
new File("C:\\DATA\\data.xls"));
Workbook book = new HSSFWorkbook();
File objFile = new File(
"C:\\DATA\\user.txt");
Br = new BufferedReader(new FileReader(objFile));
LineNumberReader lineNumberReader = new LineNumberReader(new FileReader(objFile));
lineNumberReader.skip(Long.MAX_VALUE);
int lines = lineNumberReader.getLineNumber();
Sheet sheet = book.createSheet("UserData");
System.out.println("Total Rows in the File : " +lines);
int line = 0;
while ((st = Br.readLine()) != null) {
String value = st.replace("\"", "");
arraylist = value.split(",");
Row row = null;
Cell cell = null;
row = sheet.createRow(line);
for (int i = 0; i < arraylist.length; i++) {
// System.out.println(arraylist[i]);
cell = row.createCell(i);
cell.setCellValue(arraylist[i]);
}
line++;
// System.out.println("Line: " + line);
}
book.write(outFile1);
outFile1.close();
Br.close();
How my txt file look:
"userid","Subscriberid ","HeadhouseFullname",
"167fgfg611","5904fds02","ABC, XYZ C"
"200fhskdhf","876fsgj25","ACD, NNP C"
"3893fjs956","502sgfgg3","ADC, KIO C"
"918shdfd71","1029gsg57","AED, JUI C"
Currently, when the code has been executed then it prints this file value:
userid Subscriberid HeadhouseFullname
167fgfg611 5904fds02 ABC XYZ C
200fhskdhf 876fsgj25 ACD NNP C
3893fjs956 502sgfgg3 ADC KIO C
918shdfd71 1029gsg57 AED JUI C
How it should be printed:
userid Subscriberid HeadhouseFullname
167fgfg611 5904fds02 ABC, XYZ C
200fhskdhf 876fsgj25 ACD, NNP C
3893fjs956 502sgfgg3 ADC, KIO C
918shdfd71 1029gsg57 AED, JUI C
Where you can notice that HeadhouseFullname column value is full name. For example "ABC, XYZ C" where I don't want to split full name by , (Comma) delimiter throughout the file. I want to keep it as it is "ABC, XYZ C".
Currently, it's splitting wherever it see , (Comma) delimiter.
I agree that you should be using a CSV lib as commented above, but if you want to keep going down your current path, try updating your split logic to be:
while ((st = Br.readLine()) != null) {
arraylist = st.split(",");
Row row = null;
Cell cell = null;
row = sheet.createRow(line);
for (int i = 0; i < arraylist.length; i++) {
// System.out.println(arraylist[i]);
cell = row.createCell(i);
cell.setCellValue(arraylist[i].replace("\"", ""));
}
line++;
//System.out.println("Line: " + line);
}
You could start splitting the line on " characters, i.e. st.split("\""). At this point, the resulting array would contain your entries of interest plus two additional kind of strings: empty and , character only.
String[] values = str.split("\"");
Once done that, you could iterate over the resulting array only considering and processing your entries as follows:
for (int valueIndex = 0; valueIndex < values.length; valueIndex++) {
if (values[valueIndex].length() > 0 && !values[valueIndex].equals(",")) {
// DO SOMETHING WITH values[valueIndex]...
}
}
So, considering the source code you posted, the while loop would change as follows:
while ((st = Br.readLine()) != null) {
String[] values = st.split("\"");
Row row = sheet.createRow(line++);
for (int valueIndex = 0, cellIndex = 0; valueIndex < values.length; valueIndex++) {
if (values[valueIndex].length() > 0 && !values[valueIndex].equals(",")) {
Cell cell = row.createCell(cellIndex++);
cell.setCellValue(values[valueIndex]);
}
}
}
Hope this helps!
Lorenzo
I added one additional loop with following updated code and now third column is populating combine with First name, last name and middle initial:
Here below is my updated code:
String st;
BufferedReader Br = null;
FileOutputStream outFile1 = new FileOutputStream(
new File("C:\\DATA\\data.xls"));
Workbook book = new HSSFWorkbook();
File objFile = new File(
"C:\\DATA\\user.txt");
Br = new BufferedReader(new FileReader(objFile));
LineNumberReader lineNumberReader = new LineNumberReader(new FileReader(objFile));
lineNumberReader.skip(Long.MAX_VALUE);
int lines = lineNumberReader.getLineNumber();
Sheet sheet = book.createSheet("UserData");
System.out.println("Total Rows in the File : " +lines);
int line = 0;
while ((st = Br.readLine()) != null) {
arraylist = st.split("," + "\"");
for (int i = 0; i < arraylist.length; i++) {
arraylist[i] = arraylist[i].replace("\"", "");
}
Row row = null;
Cell cell = null;
row = sheet.createRow(line);
for (int i = 0; i < arraylist.length; i++) {
// System.out.println(arraylist[i]);
cell = row.createCell(i);
cell.setCellValue(arraylist[i]);
}
line++;
// System.out.println("Line: " + line);
}
book.write(outFile1);
outFile1.close();
Br.close();
I have tried using regex and it helped for example
String txt = "0, 2, 23131312,\"This, is a message\", 1212312"; System.out.println(Arrays.toString(txt.split(",(?=(?:[^\"]\"[^\"]\")[^\"]$)")));
We need to get below format
Redemption Reference Code|Status|Delivery company|Shipper Tracking Number|Comments
2006995040|Shipped|USPS|ABCD12345|Order SHIPPED
2006995042|Cancelled|||INVALID Address
2006995048|Ordered|USPS|ABCD12345|Order SHIPPED
I am using below code
private void accumulateOrdersFromPlacement(){
int count = 0;
for (int i = 0; i < orderIds.size(); i++) {
if (count == 0) {
outPutLineData.add(orderIds.get(i));
outPutLineData.add("Cancelled");
outPutLineData.add("");
outPutLineData.add(" ");
outPutLineData.add(" ");
cancelledStatusLineItems.add(orderIds.get(i));
count++;
} else if (count == 1) {
outPutLineData.add(orderIds.get(i));
outPutLineData.add("Shipped");
if (outPutLineData.contains("Shipped")) {
outPutLineData.add("USPS");
outPutLineData.add("order SHIPPED");
outPutLineData.add("");
}
shippedStatusLineItems.add(orderIds.get(i));
count++;
} else if (count == 2) {
outPutLineData.add(orderIds.get(i));
outPutLineData.add("No Longer Available");
outPutLineData.add("");
outPutLineData.add(" ");
outPutLineData.add(" ");
count++;
nlaStatusLineItems.add(orderIds.get(i));
} else if (count == 3) {
outPutLineData.add(orderIds.get(i));
outPutLineData.add("Ordered");
outPutLineData.add("");
outPutLineData.add(" ");
outPutLineData.add(" ");
orderedStatusLineItems.add(orderIds.get(i));
count = 0;
}
}
I am using below code for file creation. This is the detailed coding . This has more readability to understand code.Here i got confused about the code.We are taking order id count andbased on that this code is working.
private File createFile(final File directory) {
FileWriter fw = null;
File tempFile = null;
try {
directory.mkdir();
tempFile = new File(".//FidelityFulfillment//" + generateFileName(countyThreeLetterCode, "FidelityFulfillment", ".csv", date));
logReport(GenericConstants.NEW_LINE + "Fulfillment file creating:", tempFile.getName());
fw = new FileWriter(tempFile, true);
try (BufferedWriter writer = new BufferedWriter(new FileWriter(tempFile, true))) {
writer.write(generateHeaderLine());
writer.newLine();
for (int y = 1; y < outPutLineData.size(); y++) {
if (y % 5 < 4) {
writer.write(outPutLineData.get(y-1) + fieldSeperator);
logReport(outPutLineData.get(y - 1) + fieldSeperator);
}
else {
writer.write(outPutLineData.get(y-1));
logReport(outPutLineData.get(y));
}
if (y % 5 == 0) {
writer.newLine();
logReport("newline");
}
}
writer.close();
} catch (final IOException e) {
e.printStackTrace();
final String err = "Unable to write file due to : " + e;
logReport(GenericConstants.NEW_LINE + "Unable to create temp local File");
} finally {
fw.close();
}
}catch (Exception e){
e.printStackTrace();
}
return tempFile;
}
Getting response as
Redemption Reference Code|Status|Delivery company|ShipperTrackingNumber|Comments
2006964032|Cancelled|| |
newline
2006964034|Shipped|USPS||
newline
2006964036|No Longer Available||
Last line one pipline is getting missing
First, you loop in a strange way :
for (int y = 1; y < outPutLineData.size(); y++) {
In general, we start at 0.
But you tried to correct that with the condition :
if (y % 5 < 4) {
//System.out.print("size:"+y);
writer.write(outPutLineData.get(y-1) + fieldSeperator);
logReport(outPutLineData.get(y - 1) + fieldSeperator);
}
else {
//System.out.print("size noseperator:"+y);
writer.write(outPutLineData.get(y-1));
logReport(outPutLineData.get(y));
}
Instead, simply use an iterator to read the values, then on read the correct amount of values :
Iterator<String> it = outPutLineData.iterator();
while(it.hasNext()){
for (int j = 0; j < columnCount; ++j) {
writer.write(it.next());
if( j < columnCount - 1)
writer.write(fieldSeperator);
}
writer.newLine();
}
Example with a StringBuilder to print in console :
int columnCount = 2;
String fieldSeperator = "|";
List<String> list = Arrays.asList("foo", "1", "bar", "2");
Iterator<String> it = list.iterator();
//Safe guard !
if(list.size() % columnCount != 0)
throw new RuntimeException("The list does have the correct amount of data");
while(it.hasNext()){
for (int j = 0; j < columnCount; ++j) {
sb.append( it.next() );
if( j < columnCount - 1)
sb.append(fieldSeperator );
}
System.out.println(sb.toString());
sb.setLength(0);
}
foo|1
bar|2
Use a POJO
You are using a List<String> to hold the values, you need to know how many column you need to read to get the value. Instead, use a POJO :
public class Redemption{
String redemptionReference;
String code;
String status;
String deliveryCompany;
String shipperTrackingNumber;
String comments;
}
And create the instance in your first loop :
List<Redemption> list...
That way, you just need to iterate each instance to build your row :
for(Redemption r: list){
writer.write(r.getRedemptionReference() + fieldSeperator);
...
writer.write(r.getComments());
writer.newLine();
}
Of course, you need to use getter and setter but this is just to show what you should do.
CSV API
Big warning, writing your own CSV writer is dangerous. If you have a comment like "This is a | character". You will end up with a line like :
2006995040|Shipped|USPS|This is a | character|Order SHIPPED
That one column to many... because you should have
2006995040|Shipped|USPS|"This is a | character"|Order SHIPPED
But you are not checking that case, and this is only one case. Using a CSV API is safer and simpler.
See Any good library to read and write csv files?
this is how my txt file looks like: text file
What I did to read the ".i" and ".m" from the 2 documents
but i didn't get any result, that hash table result = null.
is there any another way to read this txt file?
while(br.ready())
{
String line = "" ; // br.readLine();
while ( (line= br.readLine()) != null)
{
//if line contains .I
if (line.contains(".I"))
{ //read the id and save it in id var
String[] result = line.split("\\s");
id = result [result.length - 1];
}
else if(line.contains(".M ")){
String[] result = line.split("\\s");
for(int i = 0; i < result.length; i++){
if(!ht.containsKey(result[i]))
{
ArrayList<tuple> temp = new ArrayList<tuple>();
int index = line.indexOf(result[i]);
tuple tmpTupl = new tuple(id+"", index+"");
temp.add(tmpTupl);
ht.put(result[i], temp);
}
}
I'm busy with a FileWriter, and with very limited knowledge of writing text files, I found a few examples of what I need, and with that I created my own coding. I'm working in NetBeans.
The Objective:
Export JTable contents to a text file on button pressed.
The Problem:
bw.write(model.getValueAt(i, j));
The pre-error show: No suitable method found for write(Output)...
What's going on here?
This is how the process works:
1)The administrator runs the First Run Configuration
2)The administrator clicks on Add User {1}
(Apps.Settings.FTRun)
3)The administrator creates the user by entering the fields. Clicking on insert, the app creates a userid, then uploads the user to the database. ALSO, it adds the username and password to the table in FTRun.It's supposed to add the elements, but it doesn't! (Code included below)
Apps.UserManager.AddUser
4)The table doesn't populate, so I type in random strings in the table. I then click on . This throws the NullPointerException
Here's my code:
1) Export Code
2) Populate Table Code
Export Code
try {
File file = new File("C:/Program Files/DocuLoc/bin/export.txt");
// if file doesnt exists, then create it
if (!file.exists()) {
file.createNewFile();
}
TableModel model = jTable1.getModel();
FileWriter fw = new FileWriter(file.getAbsoluteFile());
BufferedWriter bw = new BufferedWriter(fw);
for (int i = 0; i < model.getRowCount(); i++) {
for (int j = 0; j < model.getColumnCount(); j++) {
//Create your File Writer
bw.write(model.getValueAt(i, j));
}
}
bw.close();
JOptionPane.showConfirmDialog(this, "Table exported successfully!\nFile located at " + file);
} catch (Exception e) {
e.printStackTrace();
}
Populate Table Code
try {
Apps.Settings.FTRun ftrun = new Apps.Settings.FTRun();
DefaultTableModel model = (DefaultTableModel) ftrun.jTable1.getModel();
model.addRow(new Object[]{UploadUName, UploadPwd});
ftrun.jTable1.enableInputMethods(true);
} catch (Exception e) {
e.printStackTrace();
}
I would use:
bw.write( model.getValueAt(i, j).toString() );
which will write the String representation of any Object you might be storiung in your TableModel.
Edit:
The NPE is caused by the bw.write(model.getValueAt(i,j).toString()); line
So what is null, "bw", "model", the data from the getValue(...) method?
I'm guessing the data, in which cause you can use code like:
Object data = model.getValueAt(I, j);
if (data == null)
System.out.println("null data at - " + I + " : " + j);
else
bw.write( data.toString() );
then once you know what cell(s) are null you investigate to find out why.
None of BufferedWriter's write methods take an Object type as returned by getValueAt. You could do
bw.write((String)model.getValueAt(i, j));
Thanks to #camickr and #Reimeus for assistance in solving this!
This code shows how you write JTable contents to a text file.
If your table has values, your code should look like this:
try {
File file = new File(filePathAndFileName); //Format: C:/.../.../file.txt
// if file doesnt exists, then create it
if (!file.exists()) {
file.createNewFile();
}
//OPTIONAL: clear the file contents. Omitting this will continue
// writing the file
PrintWriter writer = new PrintWriter(file.getAbsoluteFile());
writer.print("");
writer.close();
//Start the writing process
TableModel model = jTable1.getModel();
FileWriter fw = new FileWriter(file.getAbsoluteFile());
BufferedWriter bw = new BufferedWriter(fw);
//Execute writer to write until all values in the table have been written
for (int i = 0; i < model.getRowCount(); i++) {
for (int j = 0; j < model.getColumnCount(); j++) {
Object data = model.getValueAt(i, j);
bw.write(data.toString());
}
}
//OPTIONAL - If you have multiple columns and want to separate, use the
// following instead of the execution above
//FORMAT Column1 : Column2 : ...
//new line Column1 : Column2 : ...
for (int i = 0; i < model.getRowCount(); i++) {
for (int j = 0; j < model.getColumnCount(); j++) {
Object data = model.getValueAt(i, j);
bw.write(data.toString());
//Custom coding here for the row. I used two columns
if (j == 0) {
bw.write(" : ");
} else {
}
}
bw.newLine();
}
//End the Writing Process
bw.close();
System.out.println("Writing complete");
}catch(Exception ex){
e.printStackTrace();
}
I am trying to read a text file and adding each line to a list. The list is used in prepared statement to insert the records to db. The problem is when there is 1000000 records the execution becomes too slow and some time gets Out of Memory error.
My code
while ((sRec = in.readLine()) != null) {
myCollection.add(reversePad(sRec, hmSizeLookup, colLength, tableName));
a = Utility.getPositions(sRec, hmSizeLookup, colLength);
i = i + 1;
}
for (int j = 0; j < a.length; j++) {
Field f = (Field) hmSizeLookup.get(String.valueOf(j));
sAllFields += f.getColumnName();
if (j < a.length) {
sValues += "?";
}
if (j < a.length - 1) {
sValues += ",";
sAllFields += ",";
}
}
sQ = "insert into " + tableName + "(" + sAllFields + ") values(" + sValues + ")";
ds1.executePreparedStatement(sQ, myCollection);
How can read only 1000 lines at a time from the text file and need to perform the insert operation ? This should continue until the end of text file.
Any suggestions are appreciated,
Thanks
You need to do the inserting in the file loop.
Chop the insert code out to a function, every 1000 lines call it and then myCollection.clear()
After the loop you'll need to call it again for any data after the last insert.
So something like:
int line = 0;
while ((sRec = in.readLine()) != null) {
myCollection.add(reversePad(sRec, hmSizeLookup, colLength, tableName));
a = Utility.getPositions(sRec, hmSizeLookup, colLength);
i = i + 1;
if (++line > 1000) {
doTheInsert(myCollection);
myCollection.clear();
line = 0;
}
}
doTheInsert(myCollection);
Here is one of a million possible implementations:
String sRec = null;
READ_LINES:
do {
for (int i = 0; (sRec = in.readLine()) != null && i < 1000; i++) {
myCollection.add(reversePad(sRec, hmSizeLookup, colLength, tableName));
a = Utility.getPositions(sRec, hmSizeLookup, colLength);
}
} while (sRec != null);
Pseudo code only as I'm leaving for work:
int maxLines=1000;
int currentLine=0;
while ((sRec = in.readLine()) != null) {
Add to collection
Increment currentLine
if currentLine % maxLnes == 0 {
UpdateDB(collection)
clear collection
currentLine=0
}
}
updateDB(collection) // catch any stragglers
Sorry about the lack of working code but the idea is sound and it looks like you know your way around java.