https://docs.google.com/spreadsheets/在线使用一些常用办公工具,比如excel。

如需要C#代码自动读写这些excel,则需要使用GoogleAPI。

封装的公用类:

using Google.Apis.Auth.OAuth2;
using Google.Apis.Sheets.v4;
using Google.Apis.Sheets.v4.Data;
using Google.Apis.Services;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Dynamic;
using System.Drawing;
using Color = Google.Apis.Sheets.v4.Data.Color; namespace SendSNtoGoogle
{
public class GoogleSheetsHelper
{
static string[] Scopes = { SheetsService.Scope.Spreadsheets };
static string ApplicationName = "GoogleSheetsHelper"; private readonly SheetsService _sheetsService;
private readonly string _spreadsheetId; public GoogleSheetsHelper(string credentialFileName, string spreadsheetId)
{
var credential = GoogleCredential.FromStream(new FileStream(credentialFileName, FileMode.Open)).CreateScoped(Scopes); _sheetsService = new SheetsService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = ApplicationName,
}); _spreadsheetId = spreadsheetId;
} public List<ExpandoObject> GetDataFromSheet(GoogleSheetParameters googleSheetParameters)
{
googleSheetParameters = MakeGoogleSheetDataRangeColumnsZeroBased(googleSheetParameters);
var range = $"{googleSheetParameters.SheetName}!{GetColumnName(googleSheetParameters.RangeColumnStart)}{googleSheetParameters.RangeRowStart}:{GetColumnName(googleSheetParameters.RangeColumnEnd)}{googleSheetParameters.RangeRowEnd}"; SpreadsheetsResource.ValuesResource.GetRequest request =
_sheetsService.Spreadsheets.Values.Get(_spreadsheetId, range); var numberOfColumns = googleSheetParameters.RangeColumnEnd - googleSheetParameters.RangeColumnStart;
var columnNames = new List<string>();
var returnValues = new List<ExpandoObject>(); if (!googleSheetParameters.FirstRowIsHeaders)
{
for (var i = ; i <= numberOfColumns; i++)
{
columnNames.Add($"Column{i}");
}
} var response = request.Execute(); int rowCounter = ;
IList<IList<Object>> values = response.Values;
if (values != null && values.Count > )
{
foreach (var row in values)
{
if (googleSheetParameters.FirstRowIsHeaders && rowCounter == )
{
for (var i = ; i <= numberOfColumns; i++)
{
columnNames.Add(row[i].ToString());
}
rowCounter++;
continue;
} var expando = new ExpandoObject();
var expandoDict = expando as IDictionary<String, object>;
var columnCounter = ;
foreach (var columnName in columnNames)
{
expandoDict.Add(columnName, row[columnCounter].ToString());
columnCounter++;
}
returnValues.Add(expando);
rowCounter++;
}
} return returnValues;
} public void AddCells(GoogleSheetParameters googleSheetParameters, List<GoogleSheetRow> rows)
{
var requests = new BatchUpdateSpreadsheetRequest { Requests = new List<Request>() }; var sheetId = GetSheetId(_sheetsService, _spreadsheetId, googleSheetParameters.SheetName); GridCoordinate gc = new GridCoordinate
{
ColumnIndex = googleSheetParameters.RangeColumnStart - ,
RowIndex = googleSheetParameters.RangeRowStart - ,
SheetId = sheetId
}; var request = new Request { UpdateCells = new UpdateCellsRequest { Start = gc, Fields = "*" } }; var listRowData = new List<RowData>(); foreach (var row in rows)
{
var rowData = new RowData();
var listCellData = new List<CellData>();
foreach (var cell in row.Cells)
{
var cellData = new CellData();
var extendedValue = new ExtendedValue { StringValue = cell.CellValue }; cellData.UserEnteredValue = extendedValue;
var cellFormat = new CellFormat { TextFormat = new TextFormat() }; if (cell.IsBold)
{
cellFormat.TextFormat.Bold = true;
} cellFormat.BackgroundColor = new Color { Blue = (float)cell.BackgroundColor.B / , Red = (float)cell.BackgroundColor.R / , Green = (float)cell.BackgroundColor.G / }; cellData.UserEnteredFormat = cellFormat;
listCellData.Add(cellData);
}
rowData.Values = listCellData;
listRowData.Add(rowData);
}
request.UpdateCells.Rows = listRowData; // It's a batch request so you can create more than one request and send them all in one batch. Just use reqs.Requests.Add() to add additional requests for the same spreadsheet
requests.Requests.Add(request); _sheetsService.Spreadsheets.BatchUpdate(requests, _spreadsheetId).Execute();
} private string GetColumnName(int index)
{
const string letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
var value = ""; if (index >= letters.Length)
value += letters[index / letters.Length - ]; value += letters[index % letters.Length];
return value;
} private GoogleSheetParameters MakeGoogleSheetDataRangeColumnsZeroBased(GoogleSheetParameters googleSheetParameters)
{
googleSheetParameters.RangeColumnStart = googleSheetParameters.RangeColumnStart - ;
googleSheetParameters.RangeColumnEnd = googleSheetParameters.RangeColumnEnd - ;
return googleSheetParameters;
} private int GetSheetId(SheetsService service, string spreadSheetId, string spreadSheetName)
{
try
{
var spreadsheet = service.Spreadsheets.Get(spreadSheetId).Execute();
var sheet = spreadsheet.Sheets.FirstOrDefault(s => s.Properties.Title == spreadSheetName);
int sheetId = (int)sheet.Properties.SheetId;
return sheetId;
}
catch (Exception ex)
{
throw ex;
}
}
} public class GoogleSheetCell
{
public string CellValue { get; set; }
public bool IsBold { get; set; }
public System.Drawing.Color BackgroundColor { get; set; } = System.Drawing.Color.White;
} public class GoogleSheetParameters
{
public int RangeColumnStart { get; set; }
public int RangeRowStart { get; set; }
public int RangeColumnEnd { get; set; }
public int RangeRowEnd { get; set; }
public string SheetName { get; set; }
public bool FirstRowIsHeaders { get; set; }
} public class GoogleSheetRow
{
public GoogleSheetRow() => Cells = new List<GoogleSheetCell>(); public List<GoogleSheetCell> Cells { get; set; }
}
}

调用范例:

写入数据

            var gsh = new GoogleSheetsHelper.GoogleSheetsHelper("security-details.json", "18p6CMRLbN6L4IViUIbAxce_3ij6HGlPYXkKUPR5ZkGo");

            var row1 = new GoogleSheetRow();
var row2 = new GoogleSheetRow(); var cell1 = new GoogleSheetCell() { CellValue = "Header 1", IsBold = true, BackgroundColor = Color.DarkGoldenrod};
var cell2 = new GoogleSheetCell() { CellValue = "Header 2", BackgroundColor = Color.Cyan }; var cell3 = new GoogleSheetCell() { CellValue = "Value 1"};
var cell4 = new GoogleSheetCell() { CellValue = "Value 2"}; row1.Cells.AddRange(new List<GoogleSheetCell>() {cell1, cell2});
row2.Cells.AddRange(new List<GoogleSheetCell>() { cell3, cell4 }); var rows = new List<GoogleSheetRow>() { row1, row2 }; gsh.AddCells(new GoogleSheetParameters() {SheetName="Sheet44", RangeColumnStart = , RangeRowStart = }, rows);

读取数据:

var gsh = new GoogleSheetsHelper.GoogleSheetsHelper("Google Sheets-e1ceb012eb0c.json", "18p6CMRLbN6L4IViUIbAxce_3ij6HGlPYXkKUPR5ZkGo");
var gsp = new GoogleSheetParameters() { RangeColumnStart = , RangeRowStart = , RangeColumnEnd = , RangeRowEnd = , FirstRowIsHeaders = true, SheetName = "sheet1" };
var rowValues = gsh.GetDataFromSheet(gsp);

解析数据

foreach (rowValue in rowValues) {
var name = rowValue.Name;
var color = rowValue.FavoriteColor;
var color = rowValue.Age;
}

没有列名时解析

foreach (rowValue in rowValues) {
var name = rowValue.Column1;
var color = rowValue.Column2;
var color = rowValue.Column3;
}

参考资料:

google api
https://www.hardworkingnerd.com/how-to-read-and-write-to-google-sheets-with-c/

C#-使用GoogleAPI读写spreadsheets的更多相关文章

  1. Hadoop 中利用 mapreduce 读写 mysql 数据

    Hadoop 中利用 mapreduce 读写 mysql 数据   有时候我们在项目中会遇到输入结果集很大,但是输出结果很小,比如一些 pv.uv 数据,然后为了实时查询的需求,或者一些 OLAP ...

  2. 【造轮子】打造一个简单的万能Excel读写工具

    大家工作或者平时是不是经常遇到要读写一些简单格式的Excel? shit!~很蛋疼,因为之前吹牛,就搞了个这东西,还算是挺实用,和大家分享下. 厌烦了每次搞简单类型的Excel读写?不怕~来,喜欢流式 ...

  3. ArcGIS 10.0紧凑型切片读写方法

    首先介绍一下ArcGIS10.0的缓存机制: 切片方案 切片方案包括缓存的比例级别.切片尺寸和切片原点.这些属性定义缓存边界的存在位置,在某些客户端中叠加缓存时匹配这些属性十分重要.图像格式和抗锯齿等 ...

  4. socket读写返回值的处理

    在调用socket读写函数read(),write()时,都会有返回值.如果没有正确处理返回值,就可能引入一些问题 总结了以下几点 1当read()或者write()函数返回值大于0时,表示实际从缓冲 ...

  5. Hyper-V无法文件拖拽解决方案~~~这次用一个取巧的方法架设一个FTP来访问某个磁盘,并方便的读写文件

    异常处理汇总-服 务 器 http://www.cnblogs.com/dunitian/p/4522983.html 服务器相关的知识点:http://www.cnblogs.com/dunitia ...

  6. mybatis plugins实现项目【全局】读写分离

    在之前的文章中讲述过数据库主从同步和通过注解来为部分方法切换数据源实现读写分离 注解实现读写分离: http://www.cnblogs.com/xiaochangwei/p/4961807.html ...

  7. 计算机程序的思维逻辑 (60) - 随机读写文件及其应用 - 实现一个简单的KV数据库

    57节介绍了字节流, 58节介绍了字符流,它们都是以流的方式读写文件,流的方式有几个限制: 要么读,要么写,不能同时读和写 不能随机读写,只能从头读到尾,且不能重复读,虽然通过缓冲可以实现部分重读,但 ...

  8. Spark读写Hbase的二种方式对比

    作者:Syn良子 出处:http://www.cnblogs.com/cssdongl 转载请注明出处 一.传统方式 这种方式就是常用的TableInputFormat和TableOutputForm ...

  9. C++标准库实现WAV文件读写

    在上一篇文章RIFF和WAVE音频文件格式中对WAV的文件格式做了介绍,本文将使用标准C++库实现对数据为PCM格式的WAV文件的读写操作,只使用标准C++库函数,不依赖于其他的库. WAV文件结构 ...

随机推荐

  1. fiddler抓包详解

    image.png 前言 fiddler是一个很好的抓包工具,默认是抓http请求的,对于pc上的https请求,会提示网页不安全,这时候需要在浏览器上安装证书. 一.网页不安全 1.用fiddler ...

  2. Linux 等待信号(sigsuspend)

    /* sigsuspend()函数说明 */ #include <stdio.h> #include <signal.h> /* 知识补充: sigsuspend()函数 函数 ...

  3. SpringBoot入门-JPA(三)

    什么是JPA JPA全称Java Persistence API.JPA通过JDK 5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中. pom.xml <par ...

  4. wms证书异常问题

    目前我司已定位到两个原因,详细如下, 1.  快速生成的证书存在问题,导致APACHE和NGINX显示的时间都是4号凌晨 2.  贵司在配置完成162和163两台应用的APACHE证书,以及其中10. ...

  5. SVM – 核函数

    核函数的起源是对于线性不可分的分类情况,其实可以通过p次方多项式,及非线性模型进行分类:然后对于这类非线性多次方的,其实可以按照广义线性模型来进行升维变形,使之成为线性模型,这样就可以放到SVM中来进 ...

  6. Windows 10 安装MySQL

    1.下载MySQL官网:https://www.mysql.com/ 进入官网点击DOWNLOADS ->Community->DOWNLOADS (下载社区版) 2.安装MySQL 将下 ...

  7. 使用自定义注解和AOP管理shiro权限

    一.场景 在使用shiro框架的时候,遇到了这样的需求:本系统有多个用户,每个用户分配不同角色,每个角色的权限也不一致.比如A用户拥有新闻列表的增删改查权限,而B用户只有查看新闻列表的权限,而没有删除 ...

  8. dubbo 报错问题记录:may be version or group mismatch

    凌晨时候钉钉告警群里一直大量报错: 接口异常报警:项目:mp-rest,域名:inside-mp.01zhuanche.com,IP:10.30.3.60,接口地址:/api/v3/driverLog ...

  9. 搭建FTP(win10版)以及基本FTP操作

    参考链接:https://www.jianshu.com/p/ece21421e246 一.FTP服务器搭建 控制面板 - 程序和功能 - 启动或关闭Windows功能 启动以下功能: 搜索 “Int ...

  10. Invoke 和 BeginInvoke 的真正涵义

    BeginInvoke 方法真的是新开一个线程进行异步调用吗? 参考以下代码: public delegate void treeinvoke(); private void UpdateTreeVi ...