Google Sheets API (Java) - Update Formatting - java

I am having trouble finding the documentation on updating format with the API in Java. My goal is to modify row heights and cell background colors. Does anyone know how this is accomplished or could link me to the documentation, please?
I am using Google Sheet API v4.
EDIT:
As I review, I realize now that the Google API docs are actually easy to read. Thanks to all who helped me with this.

Adjusting column width or row height
You can use spreadsheets.batchUpdate to modify row height using updateDimensionProperties request
Setting cell background color
You can use spreadsheets.batchUpdate to modify background color using updateCells request
Background color can be configured in rows -> values -> userEnteredFormat -> backgroundColor
Color values to be used for red, blue and green ranges from 0 - 1.
range determines the range of cells where the new cell properties will be applied
Example on how to set color to blue:
blue = 255/255 = 1
red = 0/255 = 0
green = 0/255 = 0
Sample Request Body:
{
"requests": [
{
"updateCells": {
"rows": [
{
"values": [
{
"userEnteredFormat": {
"backgroundColor": {
"blue": 1,
"red": 0,
"green": 0
}
}
}
]
}
],
"range": {
"endColumnIndex": 1,
"endRowIndex": 1,
"sheetId": 0,
"startColumnIndex": 0,
"startRowIndex": 0
},
"fields": "userEnteredFormat"
}
},
{
"updateDimensionProperties": {
"range": {
"sheetId": 0,
"dimension": "ROWS",
"startIndex": 0,
"endIndex": 2
},
"properties": {
"pixelSize": 160
},
"fields": "pixelSize"
}
}
]
}
Sample Output:
Additional References:
Java Quickstart - How to use Sheets API
Basic Formatting - How to change appearance of sheets and cells
Sheets API -Samples
Sheets API - REST Resources

Related

mongo-java-driver update each item of array field belonging to document applying some conditional logic

I'm working on an event collection, where each document is modeled like so:
{
"event_name": "John Doe Concert",
"event_date": "2022-01-01"
"ticket_types": [
{
"name": "Front seats",
"total": 50 (we'll call this `oldTotal1`),
"available": 25 (we'll call this `oldAvailable1`)
},
{
"name": "Back seats",
"total": 100 (we'll call this `oldTotal2`),
"available": 50 (we'll call this `oldAvailable2`)
}
]
}
Suppose I have a REST API supporting a PUT endpoint which accepts a payload like this:
{
"event_name": "Jane Doe Concert",
"event_date": "2022-02-02"
"ticket_types": [
{
"name": "Front seats",
"total": 100 (we'll call this `newTotal1`),
},
{
"name": "Back seats",
"total": 150 (we'll call this `newTotal2`),
}
]
}
As you can see, I'm looking to update the document (doesn't matter if it's update or replace as long as the operation is atomic on a document level). For each element i in the ticket_types array in the payload, we can assume newTotal[i] >= oldTotal[i]
The way I'd like my document to look like after the update:
{
"event_name": "Jane Doe Concert",
"event_date": "2022-02-02"
"ticket_types": [
{
"name": "Front seats",
"total": 100 (the value of `newTotal1`),
"available": 75 (the value of `oldAvailable1` + `newTotal1` - `oldTotal1`)
},
{
"name": "Back seats",
"total": 150 (the value of `newTotal2`),
"available": 100 (the value of `oldAvailable2` + `newTotal2` - `oldTotal2`)
}
]
}
The problem I'm having is that I would like to perform the calculations of the resulting values of total and available exclusively through Mongo's findAndUpdate operation (without fetching the document first and doing the changes via Java code after so to speak). This is because the environment the code is run in is AWS Lambda, so I don't think I can rely on any locking mechanism other than the DB's own mechanisms, nor would I want to touch MongoDB's Transaction API.
My attempt so far:
final Document result = collection.findOneAndUpdate(query, Updates.combine(
Updates.set("event_name", request.getEventName()),
Updates.set("event_date", request.getDate().toString()),
// please help me!
Updates.set("ticket_types.$[elem].total", ...)
Updates.set("ticket_types.$[elem].available", ...)
Javascript equivalent should be:
db.getCollection("events").updateOne({name: 'John Doe Concert'},
{
$set: {
"ticket_types.$[first].total": 1000,
"ticket_types.$[first].available": "ticket_types.$[first].available" + 1000 - "ticket_types.$[first].total",
"ticket_types.$[second].total": 2000,
"ticket_types.$[second].available": "ticket_types.$[second].available" + 2000 - "ticket_types.$[second].total"
}
},
{
arrayFilters: [
{ "first.name": "Front seats" },
{ "second.name": "Back seats" }
]
}
)
Edit: The goal is to update the data doing calculation using existing attributes. I feel it's possible to achieve this using an update aggregation pipeline.
I am using DocumentDB 4.0 with application layer written in Java
Thanks

How to change cells background color in the google sheets with java

I try to change the cells background color with java, and try to use the official tutorial:
https://developers.google.cn/sheets/api/guides/conditional-format?hl=ko
But after code executing, I got the error:
com.google.api.client.googleapis.json.GoogleJsonResponseException: 400 Bad Request
{
"code" : 400,
"errors" : [ {
"domain" : "global",
"message" : "Invalid requests[0].addConditionalFormatRule: Invalid ConditionValue.userEnteredValue: =LT($D2,median($D$2:$D$11))",
"reason" : "badRequest"
} ],
"message" : "Invalid requests[0].addConditionalFormatRule: Invalid ConditionValue.userEnteredValue: =LT($D2,median($D$2:$D$11))",
"status" : "INVALID_ARGUMENT"
}
I do not understand what means "=LT($D2,median($D$2:$D$11))" and where the range sets. On the screen-shot range is A2:D5 - so how to this range should be set and what wrong with this example?
Regarding where do we set the range, It is being set in AddConditionalFormatRuleRequest -> ConditionalFormatRule -> ranges
Regarding what this formula means =LT($D2,median($D$2:$D$11)),
Since this is a custom formula, $D2 will increment based on the range provided. From D2 up to D11. It will check if the current Column D row is less than the median value of range D2:D11. See LT() and MEDIAN()
Sample Request via API Explorer:
{
"requests": [
{
"addConditionalFormatRule": {
"index": 0,
"rule": {
"ranges": [
{
"sheetId": 116889903,
"startRowIndex": 1,
"startColumnIndex": 0,
"endColumnIndex": 4,
"endRowIndex": 11
}
],
"booleanRule": {
"condition": {
"type": "CUSTOM_FORMULA",
"values": [
{
"userEnteredValue": "=LT($D2,median($D$2:$D$11))"
}
]
},
"format": {
"backgroundColor": {
"red": 1,
"blue": 0,
"green": 0
}
}
}
}
}
}
]
}
In this example, the range I set is starting from rowIndex 1 which is equivalent to sheets row 2. (GridRange object is zero-based). start columnIndex is 0 since we want it to start at sheet column 1.
Notice that endRowIndex is 11 (Sheet row 12) and endColumnIndex is 4 (Sheet column 5). It is because based on GridRange, endRowIndex and endColumnIndex are exclusive which means it is not included in the range.
Output:
For a java code sample code, please refer to the official document example here.
But if you just want to change the cell background color without conditional formatting, you can use UpdateCellsRequest or RepeatCellRequest.
The difference between the 2 is that, In UpdateCellsRequest you will provide the backgroundColor in each cell in your range. While in RepeatCellRequest you only need to set the backgroundColor once and it will be reflected in all your range.
Sample Update Cells Request via API Explorer:
{
"requests": [
{
"updateCells": {
"range": {
"sheetId": 116889903,
"startRowIndex": 0,
"startColumnIndex": 0,
"endRowIndex": 1,
"endColumnIndex": 4
},
"rows": [
{
"values": [
{
"userEnteredFormat": {
"backgroundColor": {
"red": 0,
"blue": 1,
"green": 0
}
}
},
{
"userEnteredFormat": {
"backgroundColor": {
"red": 0,
"blue": 0,
"green": 1
}
}
}
]
}
],
"fields": "userEnteredFormat"
}
}
]
}
In this example, even though I set the range to A1:D1, but since I only provided 2 CellData values with background color blue and green. Only 2 cells were updated
Output:
Sample Repeat Cell Request via API Explorer:
{
"requests": [
{
"repeatCell": {
"range": {
"sheetId": 116889903,
"startRowIndex": 0,
"endRowIndex": 1,
"startColumnIndex": 0,
"endColumnIndex": 4
},
"cell": {
"userEnteredFormat": {
"backgroundColor": {
"red": 0,
"blue": 0,
"green": 1
}
}
},
"fields": "userEnteredFormat"
}
}
]
}
I only entered 1 CellData which will reflect to all the cells within the range provided.
Output:

How I resize an object in ARCore?

I show the 3D object in ArFragment. So I put .obj file and .mtl file at sampledata folder. And I right click on obj file, and select Import Sceneform Asset to add .sfa / .sfb file.
So I can show the 3d object when I mark the image, but the object is too big.
This is my .sfa file detail
{
bound_relative_root: {
x: 0.5,
y: 0,
z: 0.5,
},
materials: [
{
name: "Material.001",
parameters: [
{
baseColor: null,
},
{
baseColorTint: [
0.80000000000000004,
0.80000000000000004,
0.80000000000000004,
1,
],
},
{
metallic: 1,
},
{
roughness: 0.120695,
},
{
opacity: null,
},
],
source: "build/sceneform_sdk/default_materials/obj_material.sfm",
},
],
model: {
attributes: [
"Position",
"TexCoord",
"Orientation",
],
collision: {},
file: "sampledata/dongbaek.obj",
name: "dongbaek",
recenter: "root",
scale: 0.200000
},
version: "0.52:1",
}
I think it can resize by scale part, but I change the value, it dosen't change. same size
So How I can resize 3d object?
Is there any problem at add 3d object file to make .sfa / .sfb file?(Import Sceneform Asset)
If you know about it, please help me.
Object scaling is changed by the Scale Controller. By setting minScale and maxScale value. Before setting parent - anchor node. See example below.
// Create the Anchor.
Anchor anchor = hitResult.createAnchor();
AnchorNode anchorNode = new AnchorNode(anchor);
anchorNode.setParent(arFragment.getArSceneView().getScene());
// Create the transformable andy and add it to the anchor.
TransformableNode node = new TransformableNode(arFragment.getTransformationSystem());
// Maxscale must be greater than minscale
node.getScaleController().setMaxScale(0.02f);
node.getScaleController().setMinScale(0.01f);
node.setParent(anchorNode);
node.setRenderable(renderable);
node.select();
Different approaches depending on your project:
Change the scale value, regenerate your sfb files
Put your node into a TransformableNode and let ScaleController scale your model
Directly use setLocalScale or setWorldScale
Scale your .obj file, and then generate the .sfa and .sfb files
Use the following code to resize your model in ARCore:
TransformationSystem transSys;
transSys = MainActivity.getArFragment().getTransformationSystem();
TransformableNode myNode = new TransformableNode(transSys);
myNode.setLocalScale(new Vector3(0.25f, 0.25f, 0.25f));
myNode.setParent(anchorNode);
//myNode.setParent(sceneView.getScene());
myNode.setRenderable(myModelRenderable);
sceneView.getScene().addChild(node);
myNode.select();

ElasticSearch: Update multi fields in Script Java Plugin

I saw this snippet where update_by_query can update source directly
POST twitter/_update_by_query
{
"script": {
"inline": "ctx._source.likes++",
"lang": "painless"
},
"query": {
"term": {
"user": "kimchy"
}
}
}
instead of using painless, I wrote a native script plugin in Java because of my complex business logic.
{
"subtotal": 1000,
"markup": 2,
"total": 2000,
"items": [
{
"subtotal": 100,
"markup": 2,
"total": 200
},
{
"subtotal": 500,
"markup": 2,
"total": 1000
}
]
}
User can set markup value in the application. If user change markup to 3, I want to update markup and total field including the ones in nested object. (NOTE: I can't use painless because in my case, the logic is more complicated than just multiplies those fields. That's why I use Java)
// my plugin code
public Object run() {
// change field value of "markup"
// change field value of "total"
return true;
}
My Code is almost similar with https://github.com/imotov/elasticsearch-native-script-example/blob/master/src/main/java/org/elasticsearch/examples/nativescript/script/TFIDFScoreScript.java
I was trying with source().put("markup", 3) but I kept getting NullPointerException
ElasticSearch Version: 5.0.0
Thank you

Change row color using Google spreadsheet API

I'd like to change the row color of a spreadsheet using the Google Spreadsheet API.
I'm using JAVA, I saw it working in JavaScript but I don't found it in JAVA.
Google Sheet API Documentation is not the best to say the least but after some fiddling here is python code that works:
http = credentials.authorize(httplib2.Http())
discovery_url = ('https://sheets.googleapis.com/$discovery/rest?'
'version=v4')
service = discovery.build('sheets', 'v4', http=http, discoveryServiceUrl=discovery_url, cache_discovery=False)
spreadsheet = service.spreadsheets().get(spreadsheetId=ss.id).execute()
requests = []
for sheet in spreadsheet.get('sheets'):
sheetId = sheet.get('properties').get('sheetId')
requests.append({
"updateCells": {
"rows": [
{
"values": [{
"userEnteredFormat": {
"backgroundColor": {
"red": 1,
"green": 0,
"blue": 0,
"alpha": 1
}}}
]
}
],
"fields": 'userEnteredFormat.backgroundColor',
"range": {
"sheetId": sheetId,
"startRowIndex": 0,
"endRowIndex": 1,
"startColumnIndex": 0,
"endColumnIndex": 1
}}})
body = {
'requests': requests
}
response = service.spreadsheets().batchUpdate(spreadsheetId=ss.id, body=body).execute()
With JavaScript API you could use this:
const range = {
sheetId: 250062959, // find your own
startRowIndex: 0,
endRowIndex: 1,
startColumnIndex: 0,
endColumnIndex: 1,
};
const request = {
spreadsheetId, // fill with your own
resource: {
requests: [
{
updateCells: {
range,
fields: '*',
rows: [
{
values: [
{
userEnteredValue: { stringValue: 'message' },
userEnteredFormat: {
backgroundColor: { red: 1, green: 0, blue: 0 },
},
},
],
},
],
},
},
],
},
};
try {
const result = await client.spreadsheets.batchUpdate(request);
console.log(result);
} catch (error) {
throw `update row error ${error}`;
}
I know this is a long time since you originally asked but according to the v4 API you could technically set a conditional format that is always true with spreadsheets.batchUpdate
eg. https://developers.google.com/sheets/api/samples/conditional-formatting
May not be the easiest thing to manage but is 'technically' possible
object = {
"updateCells": {
"range": {
"sheetId": sheetId,
"startRowIndex":startRowIndex,
"endRowIndex": endRowIndex,
"startColumnIndex": startColumnIndex,
"endColumnIndex": endColumnIndex
}
"rows": [{
"values": [{
"textFormatRuns": [
{"format": {
"foregroundColor": {
"red": 0.0,
"green": 255.0,
"blue": 31.0
},
},"startIndex": 0
},
]
}
]
}]
"fields": "textFormatRuns(format)"
}
 }
Set cell color:
https://developers.google.com/apps-script/reference/spreadsheet/range#setBackground(String)
google-apps-script (JavaScript) is the only option as far as I know. It can't be done with the spreadsheet-API (gdata)

Categories