Skip to content

Instantly share code, notes, and snippets.

@JesseYan
Last active February 12, 2020 08:27
Show Gist options
  • Save JesseYan/8e8f7bf81f5a5fdf25a5c9ca31d34d5e to your computer and use it in GitHub Desktop.
Save JesseYan/8e8f7bf81f5a5fdf25a5c9ca31d34d5e to your computer and use it in GitHub Desktop.
fix oneof proto intems in repeated accures

proto define

message Sheet {
	string sheet_name=1;
	repeated Line lines=2;
}

message Line {
	repeated Cell cells=1;
}

message Cell{
	oneof DataV {
		bool BlankLineV=1;  //空行
		string StrV=2;      //字符串
		float FloatV=3;     //float数字
		int64 IntV=4;       //int数字
	}
}

//DownloadTableRequest2 下载数据格式请求体
message DownloadTableRequest2{
	string app_id=1;
	string req_id=2;
	string req_user_email=3;
	string file_name=4;
	repeated Sheet sheets=5;
}

proto generated in go files:

func (m *Line) GetCells() []*Cell {
	if m != nil {
		return m.Cells
	}
	return nil
}

type Cell struct {
	// Types that are valid to be assigned to DataV:
	//	*Cell_BlankLineV
	//	*Cell_StrV
	//	*Cell_FloatV
	//	*Cell_IntV
	DataV                isCell_DataV `protobuf_oneof:"DataV"`
	XXX_NoUnkeyedLiteral struct{}     `json:"-"`
	XXX_unrecognized     []byte       `json:"-"`
	XXX_sizecache        int32        `json:"-"`
}

func (m *Cell) Reset()         { *m = Cell{} }
func (m *Cell) String() string { return proto.CompactTextString(m) }
func (*Cell) ProtoMessage()    {}
func (*Cell) Descriptor() ([]byte, []int) {
	return fileDescriptor_8f41eda9a0b352e7, []int{4}
}

func (m *Cell) XXX_Unmarshal(b []byte) error {
	return xxx_messageInfo_Cell.Unmarshal(m, b)
}
func (m *Cell) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
	return xxx_messageInfo_Cell.Marshal(b, m, deterministic)
}
func (m *Cell) XXX_Merge(src proto.Message) {
	xxx_messageInfo_Cell.Merge(m, src)
}
func (m *Cell) XXX_Size() int {
	return xxx_messageInfo_Cell.Size(m)
}
func (m *Cell) XXX_DiscardUnknown() {
	xxx_messageInfo_Cell.DiscardUnknown(m)
}

var xxx_messageInfo_Cell proto.InternalMessageInfo

type isCell_DataV interface {
	isCell_DataV()
}

type Cell_BlankLineV struct {
	BlankLineV bool `protobuf:"varint,1,opt,name=BlankLineV,proto3,oneof"`
}

type Cell_StrV struct {
	StrV string `protobuf:"bytes,2,opt,name=StrV,proto3,oneof"`
}

type Cell_FloatV struct {
	FloatV float32 `protobuf:"fixed32,3,opt,name=FloatV,proto3,oneof"`
}

type Cell_IntV struct {
	IntV int64 `protobuf:"varint,4,opt,name=IntV,proto3,oneof"`
}

func (*Cell_BlankLineV) isCell_DataV() {}

func (*Cell_StrV) isCell_DataV() {}

func (*Cell_FloatV) isCell_DataV() {}

func (*Cell_IntV) isCell_DataV() {}

func (m *Cell) GetDataV() isCell_DataV {
	if m != nil {
		return m.DataV
	}
	return nil
}

func (m *Cell) GetBlankLineV() bool {
	if x, ok := m.GetDataV().(*Cell_BlankLineV); ok {
		return x.BlankLineV
	}
	return false
}

func (m *Cell) GetStrV() string {
	if x, ok := m.GetDataV().(*Cell_StrV); ok {
		return x.StrV
	}
	return ""
}

func (m *Cell) GetFloatV() float32 {
	if x, ok := m.GetDataV().(*Cell_FloatV); ok {
		return x.FloatV
	}
	return 0
}

func (m *Cell) GetIntV() int64 {
	if x, ok := m.GetDataV().(*Cell_IntV); ok {
		return x.IntV
	}
	return 0
}

init in go

req: &download.DownloadTableRequest2{
					AppId:        "abcdefg",
					ReqId:        "123",
					ReqUserEmail: "yanjiayi",
					FileName:     "销售数据",
					Sheets: []*download.Sheet{
						{
							SheetName: "sheet_a",
							Lines: []*download.Line{
								{
									Cells: []*download.Cell{
										{
											DataV: &download.Cell_BlankLineV{
												BlankLineV: true,
											},
										},
									},
								}, //one line
								{
									Cells: []*download.Cell{
										{
											DataV: &download.Cell_StrV{
												StrV: "时间",
											},
										},
										{
											DataV: &download.Cell_StrV{
												StrV: "2020-02-01",
											},
										},
										{
											DataV: &download.Cell_StrV{
												StrV: "2020-02-09",
											},
										},
									},
								},
							},
						},
					},
				}

use in go

func (ex *excelContext) getCellValue(cell *downloadProto.Cell) interface{} {
	//GetDataV().(*Cell_StrV)
	//switch reflect.TypeOf(cell.GetDataV()){
	switch cell.GetDataV().(type) {
	case *downloadProto.Cell_IntV:
		return cell.GetIntV()
	case *downloadProto.Cell_StrV:
		return cell.GetStrV()
	case *downloadProto.Cell_FloatV:
		return cell.GetFloatV()
	}

	return nil
}

or

for _, sheet := range req.Sheets {
			// set every sheet
			for _, line := range sheet.Lines {
				cells := line.GetCells()
				if len(cells) == 1 && cells[0].GetBlankLineV() {
					// write blank line
					if err := writeExcel(f, make([][]interface{}, 1)); err != nil {
						return err
					}
					continue
				}

				var lineContent = make([][]interface{}, 1)
				for _, cell := range cells {
					fmt.Printf("cellValue:%+v", ex.getCellValue(cell))
					lineContent[0] = append(lineContent[0], ex.getCellValue(cell))
				}

				if err := writeExcel(f, lineContent); err != nil {
					return err
				}
			}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment