PX.Data.XLSXReader not reading first row - acumatica

I'm using the XLSXReader to read an Excel file, but it is failing to read the first row. I need to read the first row since it contains data and not headers.
Using test data, I put in a blank first row, but it still skipped the first row with data:
I copied the first row and duplicated it and it read the row:
I don't know why it is automatically skipping the first row.
Here is the action button code that imports the file, saves it, and reads it:
public PXAction<PMProject> importCostBudget;
[PXButton(CommitChanges = true)]
[PXUIField(DisplayName = "Import Cost Budget")]
protected void ImportCostBudget()
{
if (ImportCostBudgetView.AskExt() == WebDialogResult.OK)
{
const string PanelSessionKey = "ImportCostBudget";
PX.SM.FileInfo info = (PX.SM.FileInfo)PX.Common.PXContext.SessionTyped<PXSessionStatePXData>().FileInfo[PanelSessionKey];
Byte[] bytes = info.BinData;
System.Web.HttpContext.Current.Session.Remove(PanelSessionKey);
if (info != null)
{
PXNoteAttribute.AttachFile(Base.Project.Cache, Base.Project.Current, info);
using (PX.Data.XLSXReader reader = new XLSXReader(bytes))
{
//List<PMCostBudget> costBudgets = new List<PMCostBudget>();
reader.Reset();
//This is to read the first row
RowRead(reader);
while (reader.MoveNext())
{
RowRead(reader);
}
}
}
}
}
Is there a way I can force read the very first row using the reader?

Header row is likely treated as a special case intended for reading column names.
You should be able to access it from the XLSXReader IndexKeyPairs collection:
public IDictionary<int, string> IndexKeyPairs
{
get { return _header; }
}

Related

WordProcessingDocument not preserving whitespace

I'm writing a C# program using XML and Linq that reads in data from tables stored in a word document and inserts it into an excel spreadsheet. The code I have so far does this, however it does not preserve any new lines (in the word doc the "new line" is done by pressing the enter key). Using the debugger, I can see that the new lines aren't even being read in. For example, if the text I want to copy is:
Something like this
And another line
And maybe even a third line
It gets read in as:
Something like thisAnd another lineAnd maybe even a third line
I can't separate the lines by a character as the words could be anything. This is what I have so far:
internal override Dictionary<string, string> GetContent()
{
Dictionary<string, string> contents = new Dictionary<string, string>();
using (WordprocessingDocument doc = WordprocessingDocument.Open(MainForm.WordFileDialog.FileName, false))
{
List<Table> tables = doc.MainDocumentPart.Document.Descendants<Table>().ToList();
foreach (Table table in tables)
{
TableRow headerRow = table.Elements<TableRow>().ElementAt(0);
TableCell tableSectionTitle;
try
{
tableSectionTitle = headerRow.Elements<TableCell>().ElementAt(0);
}
catch (ArgumentOutOfRangeException)
{
continue;
}
List<TableRow> rows = table.Descendants<TableRow>().ToList();
foreach (TableRow row in rows)
{
TableCell headerCell = row.Elements<TableCell>().ElementAt(0);
if (headerCell.InnerText.ToLower().Contains("first item"))
{
contents.Add("first item", row.Elements<TableCell>().ElementAt(1).InnerText);
}
else if (headerCell.InnerText.ToLower().Contains("second item:"))
{
char[] split = { ':' };
Int32 count = 2;
string str = row.Elements<TableCell>().ElementAt(0).InnerText;
String[] newStr = str.Split(split, count, StringSplitOptions.None);
contents.Add("second item:", newStr[1]);
}
**continues for many more else if statements**
else
{
continue;
}
}
}
return contents;
}
}
I'm new to using XML, so any help would be appreciated!

csv save data only in one cell instead of a row

I have the following code which writes data to the CSV file.
But instead of writing the headers each in different cell it writes all in the same cell.
When i change to "UTF-8" it works fine but writs "Gibberish" instead of correct letters when opened in Office Excel.
CSVWriter csvWrite = new CSVWriter(new OutputStreamWriter(new FileOutputStream(file),
"UTF-16"), CSVWriter.DEFAULT_SEPARATOR ,CSVWriter.NO_QUOTE_CHARACTER,
CSVWriter.DEFAULT_ESCAPE_CHARACTER, CSVWriter.DEFAULT_LINE_END);
//Add Columns headers to the excel file
String columnHeaders[] = {"אאא","בבב","גגג"};
csvWrite.writeNext(columnHeaders);
//Collect Data
ArrayList<String[]> listData = collectDataFromDBToList();
//Write/Add all line from list to the csv file
csvWrite.writeAll(listData);
csvWrite.close();
Received output
Wanted output
Thank phoenix but it did not helped.
I found the solution :) , it was just to use tab separator instead of the default one.
use: '\t' instead of CSVWriter.DEFAULT_SEPARATOR
CSVWriter csvWrite = new CSVWriter(new OutputStreamWriter(new FileOutputStream(file),
"UTF-16"),'\t' ,CSVWriter.NO_QUOTE_CHARACTER,
CSVWriter.DEFAULT_ESCAPE_CHARACTER, CSVWriter.DEFAULT_LINE_END);
Here is this code that i wrote for a project..the values outside for loop ( "WSDL Name" and "Tags" are the column header and list will contain values to be inserted). It will generate test.csv
import java.io.FileWriter;
import java.io.IOException;
public class genCSV
{
public static void main(String [] args)
{
generateCsvFile("c:\\test.csv");
}
private static void generateCsvFile(String sFileName)
{
try
{
FileWriter writer = new FileWriter(sFileName);
writer.append("WSDLName");
writer.append("Tags");
writer.append('\n');
for(int i=0;i<list.size();i++){
writer.append(list.getKey);
writer.append(list.getValueForKey);
writer.append('\n');
}
//generate whatever data you want
writer.flush();
writer.close();
}
catch(IOException e)
{
e.printStackTrace();
}
}
}

Getting Values out of a String with patterns

I have textfiles, which have attributes saved in Strings. Those Strings have a pattern like this:
[attributeName]:[value]
I can't generalize the [value], because it could be of any primitive datatype.
Saving the effectively values is not my concern, because it's depending on the user which attribute has to be loaded. The same file won't be loaded very often.
Now I have 2 problems:
1) For some reason the program which creates those files sometimes adds spaces around the : at some attributes and [value] could also contain spaces, so I have to get rid of those
2) Making the reading of those attributes more performant:
I've come up with this method:
public String getAttribute(File file, String attribute)
{
try
{
BufferedReader reader = new BufferedReader(new FileReader(file), 1024);
String line;
Pattern p = Pattern.compile(Pattern.quote(attribute), Pattern.CASE_INSENSITIVE);
while ((line = reader.readLine()) != null)
{
int i = line.indexOf(":");
if(line.charAt(i-1) == ' ')
line = line.substring(0,i-2) + line.substring(i);
if(line.charAt(i+1) == ' ')
line = line.substring(0,i) + line.substring(i+2);
if (p.matcher(line).find())
{
return line.replace(attribute, "").trim();
}
}
} catch (IOException e)
{
e.printStackTrace();
}
return null;
}
However, this method will probably be one of the most called by my application, so I can't leave it so unperformant as it is right now,
Thanks for any help!
I modified code to find appropriate line. Check example code below.
If you have a lot of files and attributes in these files you could think about saving somewhere pair attribute=value in code. In example code I provided very primitive cache by using Table interface from guava library.
Example code:
# guava library
import com.google.common.collect.Table;
import com.google.common.collect.HashBasedTable;
# apache commons lang
import static org.apache.commons.lang.StringUtils.startsWithIgnoreCase;
# apache commons io
import static org.apache.commons.io.IOUtils.closeQuietly;
[...]
# very primitive cache implementation. To find a value in table you have to
# pass row and column keys. In this implementation row is equal to file
# absolute path (because you can have 2 files with the same name) and column
# is equal to attribute name.
# If you have a lot of files and attributes probably you will have to clear
# from time to time the cache otherwise you will get out of memory
private static final Table<String, String, String> CACHE = HashBasedTable.create();
[...]
public String getAttribute(File file, String attribute) {
# get value for the given attribute from the given file
String value = CACHE.get(file.getAbsolutePath(), attribute);
# if cache does not contain value, method will read value from file
if (null == value) {
BufferedReader reader = null;
String value = null;
try {
reader = new BufferedReader(new FileReader(file), 1024);
String line;
while ((line = reader.readLine()) != null) {
# From your description I understood that each line in file
# starts with attribute name
if (startsWithIgnoreCase(line, attribute) {
# if we found correct line we simple split it by ':'
String[] array = line.split(":");
# this is to ensure that line contains attribute name
# and value
if (array.length >= 2) {
# we found value for attribute and we remove spaces
value = array[1].trim();
# we put value to the cache to speed up finding
# value for the same attribute in the future
CACHE.put(file.getAbsolutePath(), attribute, value);
break;
}
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
# you should always close
closeQuietly(reader);
}
}
return value;
}

Delete Specific record in RMS?

I am creating one J2ME application which read/write RMS record. I able to read and write
record in RMS but now problem is that I want to delete record by accepting some value
like accountNumber.
Format of RMS record.
101,ABC,12345,12345
and String str contain following data.
String str=accountSrNumber +","+ name +","+ balance +","+ TextDeposit;
deleteRecStore(str,accountSrNumber);
And I need to accept accountNumber(101) from user and need to delete this record.
Here is my Delete method.
public void deleteRecStore(String str, String accNumber121) //
{
int s=str.indexOf(accNumber121);
System.out.println("index in delete function"+s);
if(s==0)
{
try{
rs.deleteRecord(s);
// RecordStore.deleteRecordStore(REC_STORE);
System.out.println("record delete successfully");
}
catch (Exception e)
{}
}
}
I tried to use both of method rs.deleteRecord(s) and RecordStore.deleteRecordStore(REC_STORE);.
But none helps.
You always delete record 0 which is the first record, which is a bad idea.
For example, if you add two records, and delete them, and than add another record, it will be indexed as 2, so you will have to call deleteRecord(2) to remove it.
Method deleteRecordStore() removes entire recordStore (which contains records) - after that, if you create one, the next added record will be indexed as zero.
If I got the idea, you want to delete a record by it's acoountNumber.
If i'm right, you need to find the recordID by it's contents. The code will probably look like this (may have mistakes, did not test it, but the idea is important):
public void deleteRecStore(String accNumber121) {
RecordEnumeration e = rs.enumerateRecords();
int found = -1;
while (e.hasMoreElements()) {
int id = e.nextRecordId();
String next = new String(e.nextRecord());
if (next.startsWidth(accNumber121)) {
found = id;
}
}
if (found == -1) {
System.out.println("not found!");
} else {
rs.deleteRecord(found);
}
}

adding an image component to Table cell by overidding `createCell`

I am using LWUIT and showing data with Table, say, flight information!
Instead of writing air companies with text I just like to replace them with icons.
So, I need to override protected Component createCell(Object value, final int row, final int column, boolean editable) method of Table.
This is how I've implemented:
Initializing
imgAln[i]=null;
try {
imgAln[i] = Image.createImage(strPathToImage[i]);
//e.g /uta.png,/somonair.png and so on
lAln[i] = new Label(imgAln[i]);
} catch (IOException e) { }
Creating Table object
Table table = new Table(model) {
protected Component createCell(Object value, final int row,
final int column, boolean editable) {
final Component c = super.createCell(value, row, column, editable);
if (column == 6) {
return lAln[value]; //it does not work here
}
}
};
need help to add Image to table cell!!!
Is there any example??? links are welcome!
The problem in your createCell(...) implementation is that it does not return the super.createCell(...) when the column is not 6. Also your array of labels (lAln) may not be properly created. Try my implementation below, but make sure you store the appropriate image name in the table models' column 0.
This should solve it:
TableModel model = new DefaultTableModel(
new String[]{"Uneditable", "Editable", "CheckBox", "Multiline"},
new Object[][]{
{"/animations.png", "", new Boolean(false), "Multi-line text\nright here"},
{"/buttons.png", "", new Boolean(true), "Further text that\nspans lines"},
{"/dialogs.png", "", new Boolean(true), "No span"},
{"/fonts.png", "", new Boolean(false), "Spanning\nFor\nEvery\nWord"},
});
Table table = new Table(model) {
protected Component createCell(Object value, final int row,
final int column, boolean editable) {
if (row != -1 && column == 0) {
try {
//In my case Column 0 store the resource path names
return new Label(Image.createImage((String)value));
} catch (Exception ex) {
ex.printStackTrace();
}
}
return super.createCell(value, row, column, editable);
}
};
NOTE: If you see the names instead of images in column 0 it means the image path is incorrect, fix it to see the images.
Did you manage to have a look at TableLayoutDemo.java in project LWUITDemo? If i remember it correct, this comes bundled download package LWUIT1.5.zip (or you can always google it).
Let me know if you need more specific help.

Resources