JXL Column Span - jxl

I have multiple rows in my excel, where contents are small except the top row.
Just in order to insert a big title in the top row, i would not like the width of subsequent rows' to be impacted.
Is there a way i can span the content in the top row over multiple columns and without affecting the width of subsequent rows.

Yes, by using the WritableSheet.mergeCells method.
For example:
WritableWorkbook w = Workbook.createWorkbook(outputStream);
WritableSheet s = w.createSheet("MySheet", 0);
int row = 0;
WritableCell titleCell = new Label(0, row, "Hello World");
s.addCell(titleCell);
s.mergeCells(0, row, 13, row);
This has the effect of making the first row be 13 cells wide, and will not effect the cell widths of the subsequent rows. Note, this will allow you to merge rows but this will not work. The correct way to change the row height is by:
/* Row heights are in 20ths of a point */
int fontPointSize = 16;
int rowHeight = (int) ((1.5d * fontPointSize) * 20);
s.setRowView(row, rowHeight, false);

This is possible, play around with this. Hope it will help you.
int col1 = 0;
int col2 = 2;
int row1 = 0;
int row2 = 0;
WritableWorkbook workbook = Workbook.createWorkbook(outputStream);
WritableSheet sheet = workbook.createSheet("MySheet", 0);
sheet.mergeCells(col1,row1,col2,row2);
//This makes the cell at row1 and col1 span the next two cells
//Write content at the marge cell
sheet.addCell(new Label(col1,row1,"Content here"));
References:
first reference and socond reference

Related

For loop runs again after condition is met

I'm working on crating a function that adds data from numerous sheets in a Google Sheets document. The function creates production sheets that has a name and data slot as well as column titles for data that the function will paste into the sheet "Print". I am having an issue where a for loop seems to run an additional time even though the conditions are met as far as I can tell. Here is the code I have so far, its ugly but I'm just building this for myself.
function pasteToPrint(){
var ui = SpreadsheetApp.getUi()
var spreadsheet = SpreadsheetApp.getActive();
var sheetName;
var sheets = SpreadsheetApp.getActiveSpreadsheet().getSheets();
var lastCol;
var lastRow;
var a;
var x;
var y;
var z;
var array1 = [];
var array2 = [];
function getNextPage(){ // spreads subsequent data set to page break for printing
x = spreadsheet.getSheetByName("Print").getLastRow();
y = x/32;
y = Math.ceil(y);
z = 32*y;
return z;
}
for(var i = sheets.length-1; i > 4; i--){ // loops through the appropriate sheets and pushes to array1
lastCol = spreadsheet.getSheetByName(sheets[i].getName()).getLastColumn()+1;
lastRow = spreadsheet.getSheetByName(sheets[i].getName()).getLastRow()+1;
array1.push(spreadsheet.getSheetByName(sheets[i].getName()).getRange(1, 1, lastRow, lastCol).getValues());
}
for(var i = 0; i < array1.length; i++){
for(var j = 0; j < array1[i].length; j++){
// Looking for data that has a value grater than 0 at .slice(2,3)
if(array1[i][j].slice(2,3) > 0){ // Ref1
for(var k = 0; k < array1[i].length; k++){ // here I push that data to array2
if(array1[i][k].slice(2,3) > 0){ // ref 2
array2.push(array1[i][k]);
}
}
ui.alert(array2+" test 1"); // lets me know the content of array2
ui.alert(array2.length); // tells me the length just to be sure
for(var l = 0; l < array2.length; l++){ // decides where to paste the next data set
if(spreadsheet.getSheetByName("Print").getLastRow()>1){ // ref 3
a = getNextPage(); // returns the next 32nd line
}
else {
a = 1; // starts at row 1
}
// this next section is column formatting for the beginning of the production sheet
// ref 4
spreadsheet.getSheetByName("Print").getRange(a,1).setValue("Name:");
spreadsheet.getSheetByName("Print").getRange(a,3).setValue("Date:");
a++; // moves to the next row
spreadsheet.getSheetByName("Print").getRange(a,1).setValue("Product");
spreadsheet.getSheetByName("Print").getRange(a,2).setValue("Work Order");
spreadsheet.getSheetByName("Print").getRange(a,3).setValue("Planned Production");
spreadsheet.getSheetByName("Print").getRange(a,4).setValue("Product Produced");
spreadsheet.getSheetByName("Print").getRange(a,5).setValue("Steel Shortage");
spreadsheet.getSheetByName("Print").getRange(a,6).setValue("Notes");
a++ // moves to the next row
// ref 5
for(var m = 0; m < array2[l].length-1; m++){ // HERE IS THE PROBLEM LOOP
ui.alert(array2[m]+" test 2"); // I see this run an additional time after m = length
spreadsheet.getSheetByName("Print").getRange(a,1).setValue(array2[m][0]);
spreadsheet.getSheetByName("Print").getRange(a,2).setValue(array2[m][4]);
spreadsheet.getSheetByName("Print").getRange(a,3).setValue(array2[m][2]);
a++;
}
}
array2 = []; // array2 is emptied
break; // First if statement checking .slice(2,3) now has the function go to the next sheet
}
}
}
ui.alert("Function ended"); // just letting me know
};
imagine that there are numerous sheets in this document with data like the following except that there might be hundreds of rows after the column titles with different part numbers and so on
Material Req Planned Quantity MTs Planned Order
AI UPC300 1 1 86 12744851
The Plan Quantity column is what the .slice(2,3) is looking for. By default when I paste the original data into the sheets from my inventory system the value of Planned Quantity will be 0. After I have gone through the document and planed production, this means I have assigned a value to planned quantity greater than 0, I will run the function to paste the data to the print sheet. There could be hundred of items but I will only plan a portion of them, that's why this is handy. I can't share the full document I'm working with because it has sensitive data in it. If you create a google sheet with one sheet named print and a second sheet named whatever you want you can then paste the example data on rows 1 and 2 of the second sheet and you will see the error I get which is
TypeError: Cannot read property '0' of undefined (line 138, file "arrayTest")
You must also change for(var i = sheets.length-1; i > 4; i--) to for(var i = sheets.length-1; i > 1; i--), change the 4 to a 1. I have more code in my document but it is comprised of separate functions from this function.
I have added an image below that showcases how this would look before I utilize the function as well as how the Print sheet would look after the function has run. I had to screenshot this unfortunately so the data is condensed. Imagine that each section of data you see, green, blue, and white, are on their own sheets. For clarity the data in green would be contained in TestSheet1, the data in blue in TestSheet2, and the Print sheet would be totally blank before this function runs. Once I have entered my planned quantities in the Planned Quantity columns of TestSheet 1 and 2 I would then run the function. This would result in the data being pasted to the print page. I have added "ref" comments to the code to show where each step of the following explanation occurs. The function runs in this order: 1) The function will determine if a sheet has any values greater than zero in the Planned Quantity column, "ref 1". 2) The function would them loop through the sheet and push any row that met this criteria to array2, "ref 2". 3) The function will determine where to paste the data into the Print sheet based on data that may already by pated to the sheet, row 1, row 32, row 64, and so on, "ref 3". 4) the function will paste a header above the soon to be pasted data. This header include name, date, and column titles. 5) Once the header is placed the function will loop through array2 and paste is contents to the Print sheet, "ref 5". 6) the function will set array2 so that array2 = [] and will then repeat the process for the next sheet until all the sheets have been gone over and there is no more data to paste into Print, "ref 6".
The m loop is unnecessary. It's looping over current row(ls) columns. A mcve looks like this:
const array2d = [1, 2, 3].map(num => new Array(6).fill(num));//boilerplate to simulate array2
console.log({array2d});
for (var l = 0; l < array2d.length; l++) {
for (var m = 0; m < array2d[l].length - 1; m++) {
// HERE IS THE PROBLEM LOOP
// alert(array2d[m] + ' test 2'); // I see this run an additional time after m = length
console.log(array2d[m][0], array2d[m][2], array2d[m][4]);
}
}
Solution:
Remove the loop entirely.
a++; // moves to the next row
// for(var m = 0; m < array2[l].length-1; m++){ // HERE IS THE PROBLEM LOOP
// ui.alert(array2[m]+" test 2"); // I see this run an additional time after m = length
spreadsheet
.getSheetByName('Print')
.getRange(a, 1)
.setValue(array2[l][0]);
spreadsheet
.getSheetByName('Print')
.getRange(a, 2)
.setValue(array2[l][4]);
spreadsheet
.getSheetByName('Print')
.getRange(a, 3)
.setValue(array2[l][2]);
a++;
// }
}
Best practices:
Essential optimization

Implementing scrollpane in Libgdx

I am trying to make a scrollable table in libgdx. Each row has 4 columns and depending on an integer total number of images in a table increases along with the rows.
I am adding images in a table, which i added to scrollpane and finally the scrollpane is added to another table which is added to the stage.
private void setCards(int row, int columns, int wins) {
//This function adds images to the table
int r ;
if(wins%columns == 0)
r=wins/columns;
else
r = wins/columns + 1;
for (int j = 0; j < r; j++) {
for (int i = 1; i <= columns; i++) {
if (j * columns + i <= wins) {
int k =j*columns+i;
if(k>12)
k= (k%12) + 1;
winningCard = new Texture(Gdx.files.internal("cards/winning_card" + String.valueOf(k)+ ".png"));
Image image = new Image(winningCard);
mTable.add(image).colspan(1).pad(10);
}
else {
scoreCard = new Texture(Gdx.files.internal("cards/score_card.png"));
Image background = new Image(scoreCard);
mTable.add(background).colspan(1).pad(10);
}
mTable.pad(10);
}
mTable.row();
}
}
After this i'm adding the table to scrollpane
mTable.setFillParent(true);
pane = new ScrollPane(mTable);
pane.setScrollingDisabled(true,false);
pane.setScrollBarPositions(true,false);
pane.setFillParent(true);
pane.setClamp(true);
table.add(pane);
table.setFillParent(true);
stage.addActor(table);
The problem i'm facing is, there is a lot of blank space, i have to scroll down to get to the images. I want the screen to start at the first row.
Don't use setFillParent(true) on a table inside a ScrollPane. It causes your problems.
If you want to expand your Table to the size of the scrollpane, use expand()/expandX()/expandY().

Fit image in EPPlus to total column width

I have the following code:
for (int i = 1; i <= columnArr.Length; i++)
{
sheet.Column(i).AutoFit();
totalWidth += sheet.Column(i).Width;
}
if (image != null)
{
int percent = (int)(totalWidth* 100 / image.Image.Width);
sheet.Row(1).Height = percent * image.Image.Height / 100;
image.SetSize(percent);
}
I want this code should make image (of type ExcelPicture) be as wide as the columns in the relevant part of the sheet (in my case, 3 columns); however, the image is much smaller. However, the row does end up the correct height for the image as shown in the file. How can I fix the width of the image?
You could use the other SetSize method.
SetSize(width, height)
Getting the details right was tricky but this worked for me:
report.Sheet.Column(columnIndex).Width = 10;
report.Sheet.Row(rowIndex).Height = 50;
picture.To.Column = picture.From.Column = columnIndex - 1;
picture.To.Row = picture.From.Row = rowIndex - 1;
picture.SetSize(70, 66);
Note that the column and row index is off by one.

How to get the number of columns in a list control

I need to get the number of columns in a list control in report mode.
Right now I'm sending a LVM_GETCOLUMN with increasing column number until SendMessage returns FALSE:
int col;
for (col = 0;; col++)
{
LVCOLUMN Column;
Column.mask = LVCF_WIDTH;
if (!::SendMessage(hWnd, LVM_GETCOLUMN, col, (LPARAM)Column)
break;
}
But this is rather awkward.
You can retrieve the number of columns from the header control of the list control.
HWND hWndHdr = (HWND)::SendMessage(hWnd, LVM_GETHEADER, 0, 0);
int count = (int)::SendMessage(hWndHdr, HDM_GETITEMCOUNT, 0, 0L);

nested looping in android

I am having an array of images.
I need to display 3 images in a row and then the next in another row.
How to do this using nested for loops. can anyone help me over this?
thanks.
Its simple, use GridView with 3 columns.
<GridView
android:layout_height="wrap_content"
android:id="#+id/gridView1"
android:layout_width="match_parent"
android:numColumns="3"
android:horizontalSpacing="10dp"
android:verticalSpacing="10dp">
The basic nested loop structure looks like this:
int imageIndex = 0;
for (int row = 0; row < rowCount; row++) {
for (int column = 0; column < columnCount; column++ {
// Draw your image here at x position of (column * image width)
// and y position of (row * image height). Add a bit to each if you
// want some spacing between your images.
// For example:
drawMyImage(images[imageIndex++], column * imageWidth, row * imageHeight);
}
}
You need two loops.
The outer loop is for the rows. Each element in the row corresponds with a column, so the inner loop is for the columns.

Resources