CSV Generation, Date and Long number formats - java

I am generating a CSV file on the fly/runtime with JSF and the code is as follows
FacesContext context = FacesContext.getCurrentInstance();
HttpServletResponse response = HttpServletResponse)context.getExternalContext().getResponse();
int read = 0;
byte[] bytes = new byte[1024];
response.setContentType("text/csv");
response.setHeader("Content-Disposition", "attachment;filename=\"" + fileName + "\"");
ServletOutputStream os = null;
StringBuffer stringBuffer1 = new StringBuffer("");
stringBuffer1.append("Disconnect Time");
stringBuffer1.append(',');
stringBuffer1.append("Calling Number");
stringBuffer1.append("01/06/2010 01:00:35 AM");
stringBuffer1.append(", ");
stringBuffer1.append("447744369900");
ByteArrayInputStream bis1;
try {
bis1 = new ByteArrayInputStream(stringBuffer1.toString().getBytes("UTF-8"));
os = response.getOutputStream();
while ((read = bis1.read(bytes)) != -1) {
os.write(bytes, 0, read);
}
os.flush();
os.close();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
FacesContext.getCurrentInstance().responseComplete();
and below is the content of the file when opened
Disconnect Time Calling Number
1/6/2010 1:00 4.47744E+11
The Actual expected result will be complete date format w.r.t AM/PM and number in complete length.
I have already tried example of double quotes as given Excel CSV - Number cell format and some other of adding blank space but they did not worked. Also the user will be performing arithmetic operation on the number columns.
Thanks in advance.

I'm no JSF expert but this seems entirely related to how Excel reads this information.
I tried playing a bit with the data, but could not make it do what you want it to do in CSV.
I created a sample CSV file with this content (using Nopepad++):
Disconnect Time, Calling Number
01/06/2010 01:00:35 AM,447744369900
And when I viewed it using Excel it gave me the same output you got - so the question you are facing is related to showing CSV in Excel - and not JSF.

You've mentioned that you're generating the file dynamically. If you are exporting data from a dataTable you might want to consider using the p:dataExporter component from PrimeFaces (you'll have to use a p:dataTable though). It may save you programatically creating the excel file if it's already in the correct structure in your dataTable.
Then it's as easy as attaching p:dataExporter to a link, and pointing it to your dataTable (tbl in this case).
<h:commandLink>
<p:graphicImage value="/images/excel.png" />
<p:dataExporter type="xls" target="tbl" fileName="cars" />
</h:commandLink>
It also supports CSV and PDF by the way.

RonK is right. There is no way you can tell Excel how to format the data when using a CSV file. Excel just uses a best guess as to what the data in the CSV columns are and then applies the default format for that type of data.
It is very likely that Excel still has the correct data (i.e. still has the seconds of your time column) and it is just an issue with formatting in Excel.
Have you tried applying a different format in Excel?
You will either have to tell the users how to format the data correctly in Excel or you have to create an Excel file directly (e.g. using Apache POI) and applying the correct format that way.

Sorry, looks like a bug ("feature", "deficit") in Excel.
It assumes anything that looks like a number is a number (and loses precision when reading it).
The simplest way probably is to ensure that the phone numbers do not look like numbers.
For example by including ( and similar characters.
Remeber that in Excel you are sometimes expected to write '=123+456 if you don't want it to compute the equation. Try this, too.
Date is probably just formatting, try formatting the column to include seconds.

To show correct format for dates and numbers in CSV I used =("447744369900") approach. The disadvantage is this that we cannot perform arithmetic operations on the cell. Now as Discussed with RonK and Turismo I am now shifted to Apache Excel library that allows you to define the format of the Excel file and create a XLS file instead of CSV. It is little slower than CSV but fulfills my requirements. See API to write huge excel files using java
Thanks again RonK and Turismo

After you open the CSV in excel, you can change the format of the "calling number" cells as Number. Select column -> Format Cells -> Change to Number

Related

while Parsing TXT to CSV using JAVA long numbers are getting converted to exponential

I have big txt file which needs to converted to CSV format using JAVA ,
I am parsing the file but file is having some long nos in a column which is getting converted to exponential .
like :89148000006119921953 ->8.9148E
I need to parse the txt to csv in such a way so what csv opens with excel doesn't not convert to exponentials values
Please find the below code :
public static String converter(String filename) throws Exception {
FileWriter writer = null;
if (filename.toString().endsWith("TXT")) {
File file = new File("C:\\convertertool\\inputFiles\\" + filename + "");
Scanner scan = new Scanner(file);
filename = filename.replace("TXT", "CSV");
File file2 = new File("C:\\convertertool\\ParsedFiles\\" + filename + "");
file.createNewFile();
writer = new FileWriter(file2);
while (scan.hasNext()) {
String csv = scan.nextLine().replace("|", ",");
System.out.println(csv);
writer.append(csv);
writer.append("\n");
writer.flush();
}
}
return filename;
}
Double.parseDouble("891413E")//or BigDecimal.parse...
Can help you
The assumptions are:
(1) You want to open the CSV file (e.g. test.csv) in Excel by double-clicking on the file, so that the data is displayed as a sequence of digits (instead of using scientific notation).
(2) You do not want to perform any manual formatting on the Excel file, after it has been opened (so, for example you do not want to have to change the Excel cell formatting).
(3) You do not want to use the Excel manual import wizard.
The only way I know of doing this is to write an Excel formula to the CSV file, instead of writing the actual, unadulterated numeric value. You can use any Excel formula which converts the number to a string.
For example, if the numeric value is this:
89148000006119921953
then the CSV file needs to contain the following (I added field one just for this demo):
field one,"=TEXT(89148000006119921953,""#"")"
You can try this for yourself by pasting the above into a test.csv file, and seeing what happens when you double-click on it.
The result in Excel is this:
In this case the Excel formula (if created directly in Excel) would be this:
=TEXT(1234567890123450000,"#")
So in the CSV file, we have to surround the field in double quotes, and we have to escape the double quotes inside the formula by doubling them.
There are some disadvantages to doing this:
(a) The text file no longer contains the pure, unchanged data. It contains an Excel formula instead. So it is more-or-less useless outside of Excel.
(b) The value in Excel is a text formula not a number (so you can't perform arithmetic on it).
(c) The Excel column widths will not auto-resize, so if there is any data in cell C1, then cell B1's display will be truncated (but the full text will still be there).
(d) Now you almost certainly do need a proper Java CSV parsing library to make sure you generate valid CSV data.
Final thought: If the end result needs to be viewed in Excel (and only in Excel), then maybe you should generate an actual Excel file (e.g. using Apache POI) instead of generating a CSV file.

Replacing text in XWPFParagraph without changing format of the docx file

I am developing font converter app which will convert Unicode font text to Krutidev/Shree Lipi (Marathi/Hindi) font text. In the original docx file there are formatted words (i.e. Color, Font, size of the text, Hyperlinks..etc. ).
I want to keep format of the final docx same as the original docx after converting words from Unicode to another font.
PFA.
Here is my Code
try {
fileInputStream = new FileInputStream("StartDoc.docx");
document = new XWPFDocument(fileInputStream);
XWPFWordExtractor extractor = new XWPFWordExtractor(document);
List<XWPFParagraph> paragraph = document.getParagraphs();
Converter data = new Converter() ;
for(XWPFParagraph p :document.getParagraphs())
{
for(XWPFRun r :p.getRuns())
{
String string2 = r.getText(0);
data.uniToShree(string2);
r.setText(string2,0);
}
}
//Write the Document in file system
FileOutputStream out = new FileOutputStream(new File("Output.docx");
document.write(out);
out.close();
System.out.println("Output.docx written successully");
}
catch (IOException e) {
System.out.println("We had an error while reading the Word Doc");
}
Thank you for ask-an-answer.
I have worked using POI some years ago, but over excel-workbooks, but still I’ll try to help you reach the root cause of your error.
The Java compiler is smart enough to suggest good debugging information in itself!
A good first step to disambiguate the error is to not overwrite the exception message provided to you via the compiler complain.
Try printing the results of e.getLocalizedMessage()or e.getMessage() and see what you get.
Getting the stack trace using printStackTrace method is also useful oftentimes to pinpoint where your error lies!
Share your findings from the above method calls to further help you help debug the issue.
[EDIT 1:]
So it seems, you are able to process the file just right with respect to the font conversion of the data, but you are not able to reconstruct the formatting of the original data in the converted data file.
(thus, "We had an error while reading the Word Doc", is a lie getting printed ;) )
Now, there are 2 elements to a Word document:
Content
Structure or Schema
You are able to convert the data as you are working only on the content of your respective doc files.
In order to be able to retain the formatting of the contents, your solution needs to be aware of the formatting of the doc files as well and take care of that.
MS Word which defined the doc files and their extension (.docx) follows a particular set of schemas that define the rules of formatting. These schemas are defined in Microsoft's XML Namespace packages[1].
You can obtain the XML(HTML) format of the doc-file you want quite easily (see steps in [1] or code in link [2]) and even apply different schemas or possibly your own schema definitions based on the definitions provided by MS's namespaces, either programmatically, for which you need to get versed with XML, XSL and XSLT concepts (w3schools[3] is a good starting point) but this method is no less complex than writing your own version of MS-Word; or using MS-Word's inbuilt tools as shown in [1].
[1]. https://www.microsoftpressstore.com/articles/article.aspx?p=2231769&seqNum=4#:~:text=During%20conversion%2C%20Word%20tags%20the,you%20can%20an%20HTML%20file.
[2]. https://svn.apache.org/repos/asf/poi/trunk/src/scratchpad/testcases/org/apache/poi/hwpf/converter/TestWordToHtmlConverter.java
[3]. https://www.w3schools.com/xml/
My answer provides you with a cursory overview of how to achieve what you want to, but depending on your inclination and time availability, you may want to use your discretion before you decide to head onto one path than the other.
Hope it helps!

How to convert exponents in a csv file from Java

I am printing some data into a CSV file using Apache Commns CSV. One of the fields contains 15 digit number and is of type String. This field prints as exponential number in CSV instead of a complete number. I know Excel does that but is there a way in java to print it as a complete number.
I am not doing anything special. Initially I thought that Commons CSV will take care of it.
public void createCSV(){
inputStream = new FileInputStream("fileName");
fileWriter = new FileWriter("fileName");
csvFileFormat = CSVFormat.Excel.withHeader("header1", "header2");
csvFilePrinter = new CSVPrinter(fileWriter, csvFileFormat);
for(List<UiIntegrationDTO dto: myList>){
String csvData = dto.getPolicyNumber();
csvFilePrinter.PrintRecord(csvData);
}
}
Prepend apostrophe
As far as I understand from the discussion in comments, it is a question about Excel interpretation of CSV file, but the file itself contains all necessary data.
I think, csvFilePrinter.PrintRecord("'" + csvData); should help. Apostrophe requires Excel to interpret a field as a string, not as a number.

CSV and Big Values

I have string value.
The value is :
12345.123456789012345
I want to write this value to csv file from java.I use OpenCSV for this.
Here is the code.
String csv = "D:\\denemehttp\\dene.csv";
CSVWriter writer = new CSVWriter(new FileWriter(csv));
String [] country = "India#China#United States#12345.1234567890123456".split("#");
writer.writeNext(country);
writer.close();
But when I open the csv the value is :
12345.123456789
But it must be:
12345.123456789012345
And note that when I open the csv file with Notepad++ it show the true value:
12345.123456789012345
So what is the problem?
Edit:I found the solution.I try Apache POI and it works.You can set the cell type with APACHE POI and excell doesn't see the value as a number and doesn't format it.It writes the value as a string completely.
You mention that you opened up the CSV in two different applications. The first one either clips it or formats it so you don't see the true value (eg. Excel). Your program is correct.
If the application you are using is Excel which you are using to open, you need to enclose the value in double quotes (") before you write it.
The csv should look like:
"India","China","United States","12345.1234567890123456"
This is because Excel does not recognize the number with this amount of precision, it needs to be treated as a string.

Convert Word (.docx !) to html with Apache POI + fr.opensagres.xdocreport

I could implement converting the old .doc files to html only with Apache POI.
For .docx, however, I had to use the fr.opensagres.xdocreport package.
Code is pretty straightforward:
XWPFDocument document = new XWPFDocument(inputStream);
OutputStream outputStream = new ByteArrayOutputStream();
XHTMLOptions options = XHTMLOptions.create().indent(4).setImageManager(new Base64EmbedImgManager());
XHTMLConverter.getInstance().convert(document, outputStream, options);
return outputStream.toString();
However, there two issues:
embedded excel charts are ignored (the .doc conversion with Apache POI converts them to images just like it does with any other normal image)
text that has custom various format combinations is not rendered correctly, several new-lines are inserted unnecessarily. ( see input and output examples)
Does anybody know any way to fix this ?
Thank you.

Categories