how to export the data in file using java - java

I need to export the values in 4 column.values for 3 columns are populating properly.
I am having trouble with 4th column which is organization column.it is multivalued column.i.e.: it has multiple values.
I have tried to convert from object to String for organization column but didnt help.
Please see the code below:
String appname = "abc";
String path = "//home/exportfile//";
String filename = path+"ApplicationExport-"+appname+".txt";
String ret = "false";
QueryOptions ops = new QueryOptions();
Filter [] filters = new Filter[1];
filters[0] = Filter.eq("application.name", appname);
ops.add(filters);
List props = new ArrayList();
props.add("identity.name");
//Do search
Iterator it = context.search(Link.class, ops, props);
//Build file and export header row
BufferedWriter out = new BufferedWriter(new FileWriter(filename));
out.write("Name,UserName,WorkforceID,organization");
out.newLine();
//Iterate Search Results
if (it!=null)
{
while (it.hasNext()) {
//Get link and create object
Object [] record = it.next();
String identityName = (String) record[0];
Identity user = (Identity) context.getObject(Identity.class, identityName);
//Get Identity attributes for export
String workforceid = (String) user.getAttribute("workforceID");
//Get application attributes for export
String userid="";
List links = user.getLinks();
if (links!=null)
{
Iterator lit = links.iterator();
while (lit.hasNext())
{
Link l = lit.next();
String lname = l.getApplicationName();
if (lname.equalsIgnoreCase(appname))
{
userid = (String) l.getAttribute("User Name");
List orgList = l.getAttribute("Organization");
}
}
}
//Output file
out.write(identityName+","+userid+","+workforceid+","+org);
out.newLine();
out.flush();
}
ret="true";
}
//Close file and return
out.close();
return ret;
The output of this code should be:
for ex:
Name,UserName,WorkforceID,organization
abc,abc,123,xy
qwe,q01,234,xy
any help correcting this code will be greatly appreciated.

EDIT:
This should give you the output you want:
out.write(identityName+","+userid+","+workforceid+","+Arrays.toString(orgList.toArray());

you probably want to declare List orgList outside the while loop since everytime it is being created and also you are using org and i havent seen any org elsewhere in your code

Related

In itext7,how to change attach files display order by added time

I want to change my attach file order in created pdf,attachment are displayed default by name,
how to change them displayed by add time?
this is my implement method:
#Override
public boolean attachFile(String src, String dest, List<SysItemfile> attachmentpaths) {
try {
PdfName name = new PdfName(src);
PdfDocument pdfDoc = new PdfDocument(new PdfReader(src), new PdfWriter(dest));
List<String> descs = new ArrayList<String>();
int i = 0;
int j = 1;
for (SysItemfile attachmentpath : attachmentpaths) {
String filename = attachmentpath.getFilename();
//test for the file name
System.out.println("filename:"+filename);
if (descs.contains(attachmentpath.getFilename())) {
//get the file suffix
String suffix = filename.substring(filename.lastIndexOf(".") + 1);
String realname = filename.substring(0,filename.lastIndexOf("."));
filename = realname+i+"."+suffix;
i++;
} else {
descs.add(attachmentpath.getFilename());
}
PdfFileSpec spec = PdfFileSpec.createEmbeddedFileSpec(pdfDoc, attachmentpath.getFileurl(),
filename, filename, name, name);
// the first parameter is discription
pdfDoc.addFileAttachment(filename, spec);
}
pdfDoc.close();
} catch (IOException e) {
logger.error("attachFile unsuccess!");
logger.error(e.getLocalizedMessage());
return false;
}
return true;
}
After that , when i add attachment to my pdf,the cann't change the order of attachment display.
what should I do?
As long as you only add attachments, the PDF standard does not allow for prescribing the sort order a PDF viewer uses when displaying the attachments.
If, on the other hand, you make the PDF a portable collection (aka a Portfolio), you can prescribe a schema (i.e. the fields in the detail list) and the sort order (by one or a combination of those fields).
You can quite easily make your PDF with attachments a portable collection with the name and modification date sorted by the latter like this:
try ( PdfReader reader = new PdfReader(...);
PdfWriter writer = new PdfWriter(...);
PdfDocument document = new PdfDocument(reader, writer)) {
PdfCollection collection = new PdfCollection();
document.getCatalog().setCollection(collection);
PdfCollectionSchema schema = new PdfCollectionSchema();
PdfCollectionField field = new PdfCollectionField("File Name", PdfCollectionField.FILENAME);
field.setOrder(0);
schema.addField("Name", field);
field = new PdfCollectionField("Modification Date", PdfCollectionField.MODDATE);
field.setOrder(1);
schema.addField("Modified", field);
collection.setSchema(schema);
PdfCollectionSort sort = new PdfCollectionSort("Modified");
collection.setSort(sort);
}
(SortAttachments test testAttachLikeGeologistedWithCollection)
You actually even can define a custom field using a type PdfCollectionField.TEXT, PdfCollectionField.DATE, or PdfCollectionField.NUMBER by which to sort. You can set the value of such a custom field on a PdfFileSpec via its setCollectionItem method.

concat strings and insert as element to linked list java-collections

INSonly(L) is the linked list, lets say the size is '5'
completelist(o) is the linked , lets say the size is '2'
if there is match in complete list like below:
"flagtrue"+ L +o
flagtrue01
flagtrue11
flagtrue21
flagtrue30
flagtrue40
I want to place all of the below strings as one string or element in linked list.
element1 ;should contain
flagtrue01
flagtrue11
flagtrue21
and
element2 : should contain
flagtrue30
flagtrue40
The values will be dynamic. please let me know if some one can help me on this.
for(int l=0;l<INSonly.size();l++ )
{
memberid=INSonly.get(l); /*passed the element to string for each iteration*/
for(int o=0;o<completelist.size();o++ ) /*complete list size '2'*/
{
if (memberid.contains(completelist.get(o))) /* if there is match */
{
System.out.println("flagtrue"+ l +o);
}
}
}
what i have done is , used the same logic and i have created the collection frame work and place the matching values to respective directories and it is automatically matched. "if somebody having an issue like this in collection framework".
for(int l=0;l<INSonly.size();l++ )
{
memberid=INSonly.get(l); /*passed the element to string for each iteration*/
for(int o=0;o<completelist.size();o++ ) /*complete list size '2'*/
{
if (memberid.contains(completelist.get(o))) /* if there is match */
{
String flag ="flag"+l +".txt";
String filedir =workdirectory + completelist.get(o) + "/";
File thedir =new File(filedir);
thedir.mkdir();
String filepath = filedir +flag;
File file= new File(filepath);
if(!file.exists()){
file.createNewFile();
}
FileWriter fw= new FileWriter(file.getAbsoluteFile());
BufferedWriter bw = new BufferedWriter(fw);
bw.write(memberid);
bw.close();

Conversion of String to JComboBox

How do I convert string to JComboBox object model ?
Note: Im using NetBeans IDE 8.0.2
to change JComboBox from <String> to <Object>
right click on JComboBox and select properties
select code tab
click on ... button from type parameters
replace <String> to <Object> and click ok.
You don't convert a String to a ComboBoxModel. You add the String to the combo box or the ComboBoxModel.
For example:
JComboBox<String> comboBox = new JComboBox<String>();
comboBox.add( "One" );
comboBox.add( "Two" );
comboBox.add( "Three" );
Read the section from the Swing tutorial on How to Use Combo Boxes for more information and other examples.
You can also search the forum or web for other examples.
I solved the problem.
I needed to be able to grab each line independent of the other so I can use just one Text file but break it out to different j combo boxes. Below was what I did. Is there a shorter way of doing this? I will have 20 JComboBox with each having around 7 select entries. The entries for the drop down boxes are around 50 lines of selections.
public void inputFile() throws IOException{
//File reader method
FileReader file = new FileReader("c:\\jcboEntries.dat");
try (BufferedReader br = new BufferedReader(file)) {
String[] lines = new String [6];
String [] jcbo = new String [6];
try {
int i =0;
lines[0] = br.readLine();
jcbo[0] = lines[0];
jcbo0 = jcbo[0];
jcboNUMONE.addItem(jcbo0);
System.out.println(jcbo0);
lines[1] = br.readLine();
jcbo[1] = lines[1];
jcbo1 = jcbo[1];
jcboNUMONE.addItem(jcbo1);
System.out.println(jcbo1);
lines[2] = br.readLine();
jcbo[2] = lines[2];
jcbo2 = jcbo[2];
jcboNUMONE.addItem(jcbo2);
System.out.println(jcbo2);
lines[3] = br.readLine();
jcbo[3] = lines[3];
jcbo3 = jcbo[3];
jcboNUMONE.addItem(jcbo3);
System.out.println(jcbo3);
lines[4] = br.readLine();
jcbo[4] = lines[4];
jcbo4 = jcbo[4];
jcboNUMONE.addItem(jcbo4);
System.out.println(jcbo4);
lines[5] = br.readLine();
jcbo[5] = lines[5];
jcbo5 = jcbo[5];
jcboNUMONE.addItem(jcbo5);
System.out.println(jcbo5);
} catch (IOException e){}
} catch (IOException e){}
}

Java: CSV file read & write

I'm reading 2 csv files: store_inventory & new_acquisitions.
I want to be able to compare the store_inventory csv file with new_acquisitions.
1) If the item names match just update the quantity in store_inventory.
2) If new_acquisitions has a new item that does not exist in store_inventory, then add it to the store_inventory.
Here is what i have done so far but its not very good. I added comments where i need to add taks 1 & 2.
Any advice or code to do the above tasks would be great! thanks.
File new_acq = new File("/src/test/new_acquisitions.csv");
Scanner acq_scan = null;
try {
acq_scan = new Scanner(new_acq);
} catch (FileNotFoundException ex) {
Logger.getLogger(mainpage.class.getName()).log(Level.SEVERE, null, ex);
}
String itemName;
int quantity;
Double cost;
Double price;
File store_inv = new File("/src/test/store_inventory.csv");
Scanner invscan = null;
try {
invscan = new Scanner(store_inv);
} catch (FileNotFoundException ex) {
Logger.getLogger(mainpage.class.getName()).log(Level.SEVERE, null, ex);
}
String itemNameInv;
int quantityInv;
Double costInv;
Double priceInv;
while (acq_scan.hasNext()) {
String line = acq_scan.nextLine();
if (line.charAt(0) == '#') {
continue;
}
String[] split = line.split(",");
itemName = split[0];
quantity = Integer.parseInt(split[1]);
cost = Double.parseDouble(split[2]);
price = Double.parseDouble(split[3]);
while(invscan.hasNext()) {
String line2 = invscan.nextLine();
if (line2.charAt(0) == '#') {
continue;
}
String[] split2 = line2.split(",");
itemNameInv = split2[0];
quantityInv = Integer.parseInt(split2[1]);
costInv = Double.parseDouble(split2[2]);
priceInv = Double.parseDouble(split2[3]);
if(itemName == itemNameInv) {
//update quantity
}
}
//add new entry into csv file
}
Thanks again for any help. =]
Suggest you use one of the existing CSV parser such as Commons CSV or Super CSV instead of reinventing the wheel. Should make your life a lot easier.
Your implementation makes the common mistake of breaking the line on commas by using line.split(","). This does not work because the values themselves might have commas in them. If that happens, the value must be quoted, and you need to ignore commas within the quotes. The split method can not do this -- I see this mistake a lot.
Here is the source of an implementation that does it correctly:
http://agiletribe.purplehillsbooks.com/2012/11/23/the-only-class-you-need-for-csv-files/
With help of the open source library uniVocity-parsers, you could develop with pretty clean code as following:
private void processInventory() throws IOException {
/**
* ---------------------------------------------
* Read CSV rows into list of beans you defined
* ---------------------------------------------
*/
// 1st, config the CSV reader with row processor attaching the bean definition
CsvParserSettings settings = new CsvParserSettings();
settings.getFormat().setLineSeparator("\n");
BeanListProcessor<Inventory> rowProcessor = new BeanListProcessor<Inventory>(Inventory.class);
settings.setRowProcessor(rowProcessor);
settings.setHeaderExtractionEnabled(true);
// 2nd, parse all rows from the CSV file into the list of beans you defined
CsvParser parser = new CsvParser(settings);
parser.parse(new FileReader("/src/test/store_inventory.csv"));
List<Inventory> storeInvList = rowProcessor.getBeans();
Iterator<Inventory> storeInvIterator = storeInvList.iterator();
parser.parse(new FileReader("/src/test/new_acquisitions.csv"));
List<Inventory> newAcqList = rowProcessor.getBeans();
Iterator<Inventory> newAcqIterator = newAcqList.iterator();
// 3rd, process the beans with business logic
while (newAcqIterator.hasNext()) {
Inventory newAcq = newAcqIterator.next();
boolean isItemIncluded = false;
while (storeInvIterator.hasNext()) {
Inventory storeInv = storeInvIterator.next();
// 1) If the item names match just update the quantity in store_inventory
if (storeInv.getItemName().equalsIgnoreCase(newAcq.getItemName())) {
storeInv.setQuantity(newAcq.getQuantity());
isItemIncluded = true;
}
}
// 2) If new_acquisitions has a new item that does not exist in store_inventory,
// then add it to the store_inventory.
if (!isItemIncluded) {
storeInvList.add(newAcq);
}
}
}
Just follow this code sample I worked out according to your requirements. Note that the library provided simplified API and significent performance for parsing CSV files.
The operation you are performing will require that for each item in your new acquisitions, you will need to search each item in inventory for a match. This is not only not efficient, but the scanner that you have set up for your inventory file would need to be reset after each item.
I would suggest that you add your new acquisitions and your inventory to collections and then iterate over your new acquisitions and look up the new item in your inventory collection. If the item exists, update the item. If it doesnt, add it to the inventory collection. For this activity, it might be good to write a simple class to contain an inventory item. It could be used for both the new acquisitions and for the inventory. For a fast lookup, I would suggest that you use HashSet or HashMap for your inventory collection.
At the end of the process, dont forget to persist the changes to your inventory file.
As Java doesn’t support parsing of CSV files natively, we have to rely on third party library. Opencsv is one of the best library available for this purpose. It’s open source and is shipped with Apache 2.0 licence which makes it possible for commercial use.
Here, this link should help you and others in the situations!
For writing to CSV
public void writeCSV() {
// Delimiter used in CSV file
private static final String NEW_LINE_SEPARATOR = "\n";
// CSV file header
private static final Object[] FILE_HEADER = { "Empoyee Name","Empoyee Code", "In Time", "Out Time", "Duration", "Is Working Day" };
String fileName = "fileName.csv");
List<Objects> objects = new ArrayList<Objects>();
FileWriter fileWriter = null;
CSVPrinter csvFilePrinter = null;
// Create the CSVFormat object with "\n" as a record delimiter
CSVFormat csvFileFormat = CSVFormat.DEFAULT.withRecordSeparator(NEW_LINE_SEPARATOR);
try {
fileWriter = new FileWriter(fileName);
csvFilePrinter = new CSVPrinter(fileWriter, csvFileFormat);
csvFilePrinter.printRecord(FILE_HEADER);
// Write a new student object list to the CSV file
for (Object object : objects) {
List<String> record = new ArrayList<String>();
record.add(object.getValue1().toString());
record.add(object.getValue2().toString());
record.add(object.getValue3().toString());
csvFilePrinter.printRecord(record);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
fileWriter.flush();
fileWriter.close();
csvFilePrinter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
You can use Apache Commons CSV api.
FYI this anwser : https://stackoverflow.com/a/42198895/6549532
Read / Write Example

Open Microsoft Word in Java

I'm trying to open MS Word 2003 document in java, search for a specified String and replace it with a new String. I use APACHE POI to do that. My code is like the following one:
public void searchAndReplace(String inputFilename, String outputFilename,
HashMap<String, String> replacements) {
File outputFile = null;
File inputFile = null;
FileInputStream fileIStream = null;
FileOutputStream fileOStream = null;
BufferedInputStream bufIStream = null;
BufferedOutputStream bufOStream = null;
POIFSFileSystem fileSystem = null;
HWPFDocument document = null;
Range docRange = null;
Paragraph paragraph = null;
CharacterRun charRun = null;
Set<String> keySet = null;
Iterator<String> keySetIterator = null;
int numParagraphs = 0;
int numCharRuns = 0;
String text = null;
String key = null;
String value = null;
try {
// Create an instance of the POIFSFileSystem class and
// attach it to the Word document using an InputStream.
inputFile = new File(inputFilename);
fileIStream = new FileInputStream(inputFile);
bufIStream = new BufferedInputStream(fileIStream);
fileSystem = new POIFSFileSystem(bufIStream);
document = new HWPFDocument(fileSystem);
docRange = document.getRange();
numParagraphs = docRange.numParagraphs();
keySet = replacements.keySet();
for (int i = 0; i < numParagraphs; i++) {
paragraph = docRange.getParagraph(i);
text = paragraph.text();
numCharRuns = paragraph.numCharacterRuns();
for (int j = 0; j < numCharRuns; j++) {
charRun = paragraph.getCharacterRun(j);
text = charRun.text();
System.out.println("Character Run text: " + text);
keySetIterator = keySet.iterator();
while (keySetIterator.hasNext()) {
key = keySetIterator.next();
if (text.contains(key)) {
value = replacements.get(key);
charRun.replaceText(key, value);
docRange = document.getRange();
paragraph = docRange.getParagraph(i);
charRun = paragraph.getCharacterRun(j);
text = charRun.text();
}
}
}
}
bufIStream.close();
bufIStream = null;
outputFile = new File(outputFilename);
fileOStream = new FileOutputStream(outputFile);
bufOStream = new BufferedOutputStream(fileOStream);
document.write(bufOStream);
} catch (Exception ex) {
System.out.println("Caught an: " + ex.getClass().getName());
System.out.println("Message: " + ex.getMessage());
System.out.println("Stacktrace follows.............");
ex.printStackTrace(System.out);
}
}
I call this function with following arguments:
HashMap<String, String> replacements = new HashMap<String, String>();
replacements.put("AAA", "BBB");
searchAndReplace("C:/Test.doc", "C:/Test1.doc", replacements);
When the Test.doc file contains a simple line like this : "AAA EEE", it works successfully, but when i use a complicated file it will read the content successfully and generate the Test1.doc file but when I try to open it, it will give me the following error:
Word unable to read this document. It may be corrupt.
Try one or more of the following:
* Open and repair the file.
* Open the file with Text Recovery converter.
(C:\Test1.doc)
Please tell me what to do, because I'm a beginner in POI and I have not found a good tutorial for it.
First of all you should be closing your document.
Besides that, what I suggest doing is resaving your original Word document as a Word XML document, then changing the extension manually from .XML to .doc . Then look at the XML of the actual document you're working with and trace the content to make sure you're not accidentally editing hexadecimal values (AAA and EEE could be hex values in other fields).
Without seeing the actual Word document it's hard to say what's going on.
There is not much documentation about POI at all, especially for Word document unfortunately.
I don't know : is its OK to answer myself, but Just to share the knowledge, I'll answer myself.
After navigating the web, the final solution i found is :
The Library called docx4j is very good for dealing with MS docx file, although its documentation is not enough till now and its forum is still in a beginning steps, but overall it help me to do what i need..
Thanks 4 all who help me..
You could try OpenOffice API, but there arent many resources out there to tell you how to use it.
You can also try this one: http://www.dancrintea.ro/doc-to-pdf/
Looks like this could be the issue.

Categories