Compare commits
4 Commits
Author | SHA1 | Date | |
---|---|---|---|
45c7250831 | |||
f329652444 | |||
721c4ef2e0 | |||
fd48c5dc76 |
18
go.mod
18
go.mod
@ -1,6 +1,8 @@
|
|||||||
module penahub.gitlab.yandexcloud.net/backend/templategen
|
module penahub.gitlab.yandexcloud.net/backend/templategen
|
||||||
|
|
||||||
go 1.20
|
go 1.21.0
|
||||||
|
|
||||||
|
toolchain go1.23.4
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/danilsolovyov/doc-template v0.0.0-20230327151707-b8182a1ee9f4
|
github.com/danilsolovyov/doc-template v0.0.0-20230327151707-b8182a1ee9f4
|
||||||
@ -10,7 +12,7 @@ require (
|
|||||||
github.com/gorilla/schema v1.2.0
|
github.com/gorilla/schema v1.2.0
|
||||||
github.com/minio/minio-go/v7 v7.0.61
|
github.com/minio/minio-go/v7 v7.0.61
|
||||||
github.com/pkg/errors v0.9.1
|
github.com/pkg/errors v0.9.1
|
||||||
github.com/stretchr/testify v1.8.4
|
github.com/stretchr/testify v1.9.0
|
||||||
github.com/themakers/bdd v0.0.0-20210316111417-6b1dfe326f33
|
github.com/themakers/bdd v0.0.0-20210316111417-6b1dfe326f33
|
||||||
github.com/twmb/franz-go v1.14.3
|
github.com/twmb/franz-go v1.14.3
|
||||||
go.mongodb.org/mongo-driver v1.12.1
|
go.mongodb.org/mongo-driver v1.12.1
|
||||||
@ -25,6 +27,7 @@ require (
|
|||||||
cloud.google.com/go/compute v1.23.0 // indirect
|
cloud.google.com/go/compute v1.23.0 // indirect
|
||||||
cloud.google.com/go/compute/metadata v0.2.3 // indirect
|
cloud.google.com/go/compute/metadata v0.2.3 // indirect
|
||||||
github.com/andybalholm/brotli v1.0.5 // indirect
|
github.com/andybalholm/brotli v1.0.5 // indirect
|
||||||
|
github.com/beevik/etree v1.5.0 // indirect
|
||||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||||
github.com/dustin/go-humanize v1.0.1 // indirect
|
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||||
github.com/fatih/color v1.10.0 // indirect
|
github.com/fatih/color v1.10.0 // indirect
|
||||||
@ -38,6 +41,7 @@ require (
|
|||||||
github.com/json-iterator/go v1.1.12 // indirect
|
github.com/json-iterator/go v1.1.12 // indirect
|
||||||
github.com/klauspost/compress v1.16.7 // indirect
|
github.com/klauspost/compress v1.16.7 // indirect
|
||||||
github.com/klauspost/cpuid/v2 v2.2.5 // indirect
|
github.com/klauspost/cpuid/v2 v2.2.5 // indirect
|
||||||
|
github.com/lukasjarosch/go-docx v0.5.0 // indirect
|
||||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||||
github.com/mattn/go-isatty v0.0.19 // indirect
|
github.com/mattn/go-isatty v0.0.19 // indirect
|
||||||
github.com/mattn/go-runewidth v0.0.14 // indirect
|
github.com/mattn/go-runewidth v0.0.14 // indirect
|
||||||
@ -61,11 +65,11 @@ require (
|
|||||||
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect
|
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect
|
||||||
go.opencensus.io v0.24.0 // indirect
|
go.opencensus.io v0.24.0 // indirect
|
||||||
go.uber.org/multierr v1.10.0 // indirect
|
go.uber.org/multierr v1.10.0 // indirect
|
||||||
golang.org/x/crypto v0.12.0 // indirect
|
golang.org/x/crypto v0.25.0 // indirect
|
||||||
golang.org/x/net v0.14.0 // indirect
|
golang.org/x/net v0.27.0 // indirect
|
||||||
golang.org/x/sync v0.3.0 // indirect
|
golang.org/x/sync v0.7.0 // indirect
|
||||||
golang.org/x/sys v0.11.0 // indirect
|
golang.org/x/sys v0.22.0 // indirect
|
||||||
golang.org/x/text v0.12.0 // indirect
|
golang.org/x/text v0.16.0 // indirect
|
||||||
google.golang.org/appengine v1.6.7 // indirect
|
google.golang.org/appengine v1.6.7 // indirect
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230807174057-1744710a1577 // indirect
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20230807174057-1744710a1577 // indirect
|
||||||
google.golang.org/grpc v1.57.0 // indirect
|
google.golang.org/grpc v1.57.0 // indirect
|
||||||
|
29
go.sum
29
go.sum
@ -8,6 +8,8 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03
|
|||||||
github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs=
|
github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs=
|
||||||
github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
|
github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
|
||||||
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
|
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
|
||||||
|
github.com/beevik/etree v1.5.0 h1:iaQZFSDS+3kYZiGoc9uKeOkUY3nYMXOKLl6KIJxiJWs=
|
||||||
|
github.com/beevik/etree v1.5.0/go.mod h1:gPNJNaBGVZ9AwsidazFZyygnd+0pAU38N4D+WemwKNs=
|
||||||
github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A=
|
github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A=
|
||||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||||
@ -93,6 +95,8 @@ github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQs
|
|||||||
github.com/klauspost/cpuid/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
github.com/klauspost/cpuid/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||||
github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg=
|
github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg=
|
||||||
github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
|
github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
|
||||||
|
github.com/lukasjarosch/go-docx v0.5.0 h1:4vU+gJ4WMdqwRvRVFF+XMw3rPfUGSXlToPJIX3mHQsQ=
|
||||||
|
github.com/lukasjarosch/go-docx v0.5.0/go.mod h1:ka/NZgDIJId48vMvcfWfduVTY7uV0/f8EgsmCjuS9X0=
|
||||||
github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||||
@ -138,8 +142,8 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
|
|||||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||||
github.com/themakers/bdd v0.0.0-20210316111417-6b1dfe326f33 h1:N9f/Q+2Ssa+yDcbfaoLTYvXmdeyUUxsJKdPUVsjSmiA=
|
github.com/themakers/bdd v0.0.0-20210316111417-6b1dfe326f33 h1:N9f/Q+2Ssa+yDcbfaoLTYvXmdeyUUxsJKdPUVsjSmiA=
|
||||||
github.com/themakers/bdd v0.0.0-20210316111417-6b1dfe326f33/go.mod h1:rpcH99JknBh8seZmlOlUg51gasZH6QH34oXNsIwYT6E=
|
github.com/themakers/bdd v0.0.0-20210316111417-6b1dfe326f33/go.mod h1:rpcH99JknBh8seZmlOlUg51gasZH6QH34oXNsIwYT6E=
|
||||||
github.com/twmb/franz-go v1.14.3 h1:cq8rxAnVYU1uF3SRVn8eEaUf+AaXKWlB0Cl3Ca7JSa4=
|
github.com/twmb/franz-go v1.14.3 h1:cq8rxAnVYU1uF3SRVn8eEaUf+AaXKWlB0Cl3Ca7JSa4=
|
||||||
@ -176,8 +180,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh
|
|||||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||||
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||||
golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk=
|
golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30=
|
||||||
golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw=
|
golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M=
|
||||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||||
@ -192,12 +196,13 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn
|
|||||||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||||
|
golang.org/x/net v0.0.0-20200925080053-05aa5d4ee321/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||||
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||||
golang.org/x/net v0.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14=
|
golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys=
|
||||||
golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI=
|
golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE=
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
golang.org/x/oauth2 v0.11.0 h1:vPL4xzxBM4niKCW6g9whtaWVXTJf1U5e4aZxxFx/gbU=
|
golang.org/x/oauth2 v0.11.0 h1:vPL4xzxBM4niKCW6g9whtaWVXTJf1U5e4aZxxFx/gbU=
|
||||||
@ -207,8 +212,8 @@ golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJ
|
|||||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
|
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
|
||||||
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
|
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
@ -226,8 +231,8 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc
|
|||||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM=
|
golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
|
||||||
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
@ -237,8 +242,8 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
|||||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||||
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
|
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
|
||||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||||
golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc=
|
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
|
||||||
golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||||
|
@ -1,12 +1,15 @@
|
|||||||
package handlers
|
package handlers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/beevik/etree"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
"penahub.gitlab.yandexcloud.net/backend/templategen/tools"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
@ -33,22 +36,29 @@ type RespGenerated struct {
|
|||||||
|
|
||||||
// ReqGeneratorService is the request we get on GeneratorService endpoint.
|
// ReqGeneratorService is the request we get on GeneratorService endpoint.
|
||||||
type ReqGeneratorService struct {
|
type ReqGeneratorService struct {
|
||||||
DocNumber string `json:"docnumber"`
|
DocNumber string `json:"docnumber" xml:"DocNum"`
|
||||||
Date string `json:"date"`
|
Date string `json:"date" xml:"date"`
|
||||||
OrgTaxNum string `json:"orgtaxnum"`
|
OrgTaxNum string `json:"orgtaxnum" xml:"orgtaxnum"`
|
||||||
OrgName string `json:"orgname"`
|
OrgName string `json:"orgname" xml:"orgname"`
|
||||||
Name string `json:"name"`
|
Items []Item `json:"items" xml:"items>item"`
|
||||||
Amount string `json:"amount"`
|
TotalSum string `xml:"totalsum"`
|
||||||
Price string `json:"price"`
|
|
||||||
Sum string `json:"sum"`
|
|
||||||
Unit string `json:"unit"` // default value set in NewReqGeneratorService()
|
|
||||||
Tax string `json:"tax"` // default value set in NewReqGeneratorService()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewReqGeneratorService() ReqGeneratorService {
|
type Item struct {
|
||||||
return ReqGeneratorService{
|
Name string `json:"name" xml:"docnumber"`
|
||||||
Tax: "НДС не облагается",
|
Amount string `json:"amount" xml:"amount"`
|
||||||
Unit: "-",
|
Price string `json:"price" xml:"price"`
|
||||||
|
Sum string `json:"sum" xml:"sum"`
|
||||||
|
Unit string `json:"unit" xml:"unit"` // default value set in NewItem()
|
||||||
|
Tax string `json:"tax" xml:"tax"` // default value set in NewItem()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *ReqGeneratorService) NewItem() {
|
||||||
|
if r.Items != nil && len(r.Items) > 0 {
|
||||||
|
for i, _ := range r.Items {
|
||||||
|
r.Items[i].Tax = "НДС не облагается"
|
||||||
|
r.Items[i].Unit = "-"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -382,7 +392,6 @@ func (h *Handlers) GeneratorService(writer http.ResponseWriter, req *http.Reques
|
|||||||
}
|
}
|
||||||
|
|
||||||
email := req.FormValue("email")
|
email := req.FormValue("email")
|
||||||
|
|
||||||
if email == "" {
|
if email == "" {
|
||||||
err = errors.New("email required")
|
err = errors.New("email required")
|
||||||
h.reportError(writer, http.StatusBadRequest, err)
|
h.reportError(writer, http.StatusBadRequest, err)
|
||||||
@ -390,21 +399,19 @@ func (h *Handlers) GeneratorService(writer http.ResponseWriter, req *http.Reques
|
|||||||
}
|
}
|
||||||
|
|
||||||
dataString := req.FormValue("data")
|
dataString := req.FormValue("data")
|
||||||
|
|
||||||
if dataString == "" {
|
if dataString == "" {
|
||||||
err = errors.New("data required")
|
err = errors.New("data required")
|
||||||
h.reportError(writer, http.StatusBadRequest, err)
|
h.reportError(writer, http.StatusBadRequest, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// some default values filled
|
|
||||||
data := NewReqGeneratorService()
|
|
||||||
|
|
||||||
// maybe need to check required fields and report errors if missing
|
// maybe need to check required fields and report errors if missing
|
||||||
|
var data ReqGeneratorService
|
||||||
if err = json.Unmarshal([]byte(dataString), &data); err != nil {
|
if err = json.Unmarshal([]byte(dataString), &data); err != nil {
|
||||||
h.reportError(writer, http.StatusBadRequest, err)
|
h.reportError(writer, http.StatusBadRequest, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
data.NewItem()
|
||||||
|
|
||||||
formFile, formFileHeader, err := req.FormFile("file")
|
formFile, formFileHeader, err := req.FormFile("file")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -423,8 +430,8 @@ func (h *Handlers) GeneratorService(writer http.ResponseWriter, req *http.Reques
|
|||||||
h.reportError(writer, http.StatusBadRequest, err)
|
h.reportError(writer, http.StatusBadRequest, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
// TODO
|
||||||
resultFile, err := templategen.GenerateBytesFile(file, data)
|
resultFile, err := GenerateBytesFile(file, data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
h.reportError(writer, http.StatusBadRequest, err)
|
h.reportError(writer, http.StatusBadRequest, err)
|
||||||
return
|
return
|
||||||
@ -442,6 +449,92 @@ func (h *Handlers) GeneratorService(writer http.ResponseWriter, req *http.Reques
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GenerateBytesFile(file []byte, data ReqGeneratorService) ([]byte, error) {
|
||||||
|
// разархивируем документ чтобы содержимое поменять
|
||||||
|
files, err := tools.ExtractDocx(file)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// надо менять только document.xml
|
||||||
|
modifiedXML, err := modifyDocumentXML(files["word/document.xml"], data)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
files["word/document.xml"] = modifiedXML
|
||||||
|
// заменив отредактированный - опять делаем докс файл
|
||||||
|
return tools.CreateDocx(files)
|
||||||
|
}
|
||||||
|
|
||||||
|
func modifyDocumentXML(xmlContent []byte, data ReqGeneratorService) ([]byte, error) {
|
||||||
|
doc := etree.NewDocument()
|
||||||
|
if err := doc.ReadFromBytes(xmlContent); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// базовые плейсхолдеры которые просто заменяются
|
||||||
|
replaceMap := map[string]string{
|
||||||
|
"DocNum": data.DocNumber,
|
||||||
|
"Date": data.Date,
|
||||||
|
"Orgname": data.OrgName,
|
||||||
|
"INN": data.OrgTaxNum,
|
||||||
|
"Total": data.TotalSum,
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, element := range doc.FindElements("//w:t") {
|
||||||
|
if val, exists := replaceMap[element.Text()]; exists {
|
||||||
|
element.SetText(val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// создание таблицы
|
||||||
|
for _, element := range doc.FindElements("//w:t") {
|
||||||
|
if element.Text() == "ItemsTable" {
|
||||||
|
// родительские параметры находим
|
||||||
|
paragraph := element.Parent().Parent()
|
||||||
|
grandParent := paragraph.Parent()
|
||||||
|
// запоминаем где был этот абзац
|
||||||
|
prevElement := *paragraph
|
||||||
|
// дропаем старый абзац
|
||||||
|
grandParent.RemoveChild(paragraph)
|
||||||
|
|
||||||
|
// делаем таблицу
|
||||||
|
table := etree.NewElement("w:tbl")
|
||||||
|
tblPr := table.CreateElement("w:tblPr")
|
||||||
|
tblPr.CreateElement("w:tblStyle").CreateAttr("w:val", "TableGrid")
|
||||||
|
tblPr.CreateElement("w:tblW").CreateAttr("w:w", "5000")
|
||||||
|
headerRow := table.CreateElement("w:tr")
|
||||||
|
headers := []string{"№", "Наименование", "Кол-во", "Ед. изм.", "Цена за ед.", "Стоимость", "НДС"}
|
||||||
|
for _, header := range headers {
|
||||||
|
tools.CreateTableCell(headerRow, header, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
// заполняем данными
|
||||||
|
for i, item := range data.Items {
|
||||||
|
row := table.CreateElement("w:tr")
|
||||||
|
tools.CreateTableCell(row, fmt.Sprintf("%d", i+1), false)
|
||||||
|
tools.CreateTableCell(row, item.Name, false)
|
||||||
|
tools.CreateTableCell(row, item.Amount, false)
|
||||||
|
tools.CreateTableCell(row, item.Unit, false)
|
||||||
|
tools.CreateTableCell(row, item.Price, false)
|
||||||
|
tools.CreateTableCell(row, item.Sum, false)
|
||||||
|
tools.CreateTableCell(row, item.Tax, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
// вставляем таблицу на место удаленного абзаца где был плейсхолдер ItemsTable
|
||||||
|
grandParent.InsertChildAt(prevElement.Index(), table)
|
||||||
|
prevElement = *table
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
doc.Indent(4)
|
||||||
|
var buf bytes.Buffer
|
||||||
|
if _, err := doc.WriteTo(&buf); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return buf.Bytes(), nil
|
||||||
|
}
|
||||||
|
|
||||||
// generate - локальная функция, для генерации файла, возвращает ссылку для скачивания сгенерированного файла.
|
// generate - локальная функция, для генерации файла, возвращает ссылку для скачивания сгенерированного файла.
|
||||||
func (h *Handlers) generate(r *http.Request, file, name, storageID, storageType,
|
func (h *Handlers) generate(r *http.Request, file, name, storageID, storageType,
|
||||||
amoID string, history *model.History, data any) (string, error) {
|
amoID string, history *model.History, data any) (string, error) {
|
||||||
@ -461,23 +554,23 @@ func (h *Handlers) generate(r *http.Request, file, name, storageID, storageType,
|
|||||||
privilege, privilegeUnlimTimeExists := amoData.Privileges[model.PrivilegeTemplateUnlimTime]
|
privilege, privilegeUnlimTimeExists := amoData.Privileges[model.PrivilegeTemplateUnlimTime]
|
||||||
if privilegeUnlimTimeExists {
|
if privilegeUnlimTimeExists {
|
||||||
if privilege.CreatedAt.AddDate(0, 0, int(privilege.Amount)).After(time.Now()) {
|
if privilege.CreatedAt.AddDate(0, 0, int(privilege.Amount)).After(time.Now()) {
|
||||||
privilegeUnlimTimeExists = false
|
privilegeUnlimTimeExists = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !privilegeUnlimTimeExists {
|
if !privilegeUnlimTimeExists {
|
||||||
// По количеству генераций
|
// По количеству генераций
|
||||||
privilege, privilegeCountExists := amoData.Privileges[model.PrivilegeTemplateCount]
|
privilege, privilegeCountExists := amoData.Privileges[model.PrivilegeTemplateCount]
|
||||||
if privilegeCountExists {
|
if privilegeCountExists {
|
||||||
privilegeAmount = privilege.Amount
|
privilegeAmount = privilege.Amount
|
||||||
|
|
||||||
if privilegeAmount < 1 {
|
if privilegeAmount < 1 {
|
||||||
return "", errors.New("tariff ended - not enough count")
|
return "", errors.New("tariff ended - not enough count")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return "", errors.New("tariff ended - not enough count")
|
return "", errors.New("tariff ended - not enough count")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var exportURL string
|
var exportURL string
|
||||||
history.Source.File = file
|
history.Source.File = file
|
||||||
|
@ -1,68 +1,91 @@
|
|||||||
package handlers
|
package handlers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
"os"
|
"os"
|
||||||
"reflect"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/danilsolovyov/doc-template/docx"
|
|
||||||
"penahub.gitlab.yandexcloud.net/backend/templategen/templategen"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestGeneratorService(t *testing.T) {
|
//func TestGeneratorService(t *testing.T) {
|
||||||
file, err := os.ReadFile("../assets/TestGeneratorService.docx")
|
// file, err := os.ReadFile("../assets/TestGeneratorService.docx")
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
t.Error(err)
|
// t.Error(err)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// data := NewReqGeneratorService()
|
||||||
|
//
|
||||||
|
// // is filled by json.Unmarshal
|
||||||
|
// data.DocNumber = "2"
|
||||||
|
// data.Date = "13.05.2021"
|
||||||
|
// data.OrgName = `ООО ЛИГА ХОДЬБЫ "ЖЕНЬШЕНЬ" ПРИМОРСКОГО КРАЯ`
|
||||||
|
// data.OrgTaxNum = "999888111"
|
||||||
|
// data.Sum = "60 000 руб."
|
||||||
|
// data.Name = "Консультационные услуги"
|
||||||
|
// data.Amount = "2"
|
||||||
|
// data.Price = "1500"
|
||||||
|
// data.Sum = "3000"
|
||||||
|
//
|
||||||
|
// resultBytes, err := templategen.GenerateBytesFile(file, data)
|
||||||
|
// if err != nil {
|
||||||
|
// t.Error(err)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// document := new(docx.Docx)
|
||||||
|
// err = document.ReadBytes(resultBytes)
|
||||||
|
// if err != nil {
|
||||||
|
// t.Error(err)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // _ = os.WriteFile("/tmp/out3.docx", resultBytes, 0644) // TODO delete
|
||||||
|
//
|
||||||
|
// checkAllFieldsPresent(t, document.GetContent(), data)
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//func checkAllFieldsPresent(t *testing.T, content string, data interface{}) {
|
||||||
|
// t.Helper()
|
||||||
|
//
|
||||||
|
// v := reflect.ValueOf(data)
|
||||||
|
// vt := v.Type()
|
||||||
|
//
|
||||||
|
// for i := 0; i < v.NumField(); i++ {
|
||||||
|
// field := v.Field(i)
|
||||||
|
// fieldName := vt.Field(i).Name
|
||||||
|
// fieldValue := field.Interface()
|
||||||
|
//
|
||||||
|
// switch x := fieldValue.(type) {
|
||||||
|
// case string:
|
||||||
|
// if !strings.Contains(content, x) {
|
||||||
|
// t.Errorf("missing value for '%s': '%s'", fieldName, x)
|
||||||
|
// }
|
||||||
|
// default:
|
||||||
|
// t.Error("unhandled field")
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
func Test_GenerateBytesFile(t *testing.T) {
|
||||||
|
data := ReqGeneratorService{
|
||||||
|
DocNumber: "123",
|
||||||
|
Date: "2023-10-05",
|
||||||
|
OrgTaxNum: "1234567890",
|
||||||
|
OrgName: "ООО 'Пример'",
|
||||||
|
Items: []Item{
|
||||||
|
{Name: "Услуга 1", Amount: "1", Price: "1000", Sum: "1000"},
|
||||||
|
{Name: "Услуга 2", Amount: "2", Price: "500", Sum: "1000"},
|
||||||
|
},
|
||||||
|
TotalSum: "5000",
|
||||||
}
|
}
|
||||||
|
|
||||||
data := NewReqGeneratorService()
|
data.NewItem()
|
||||||
|
|
||||||
// is filled by json.Unmarshal
|
fmt.Println(data)
|
||||||
data.DocNumber = "2"
|
|
||||||
data.Date = "13.05.2021"
|
|
||||||
data.OrgName = `ООО ЛИГА ХОДЬБЫ "ЖЕНЬШЕНЬ" ПРИМОРСКОГО КРАЯ`
|
|
||||||
data.OrgTaxNum = "999888111"
|
|
||||||
data.Sum = "60 000 руб."
|
|
||||||
data.Name = "Консультационные услуги"
|
|
||||||
data.Amount = "2"
|
|
||||||
data.Price = "1500"
|
|
||||||
data.Sum = "3000"
|
|
||||||
|
|
||||||
resultBytes, err := templategen.GenerateBytesFile(file, data)
|
file, err := os.ReadFile("../static/examples/docx/report.docx")
|
||||||
if err != nil {
|
assert.NoError(t, err)
|
||||||
t.Error(err)
|
genFileBytes, err := GenerateBytesFile(file, data)
|
||||||
}
|
assert.NoError(t, err)
|
||||||
|
|
||||||
document := new(docx.Docx)
|
err = os.WriteFile("testGenBytesFile.docx", genFileBytes, 0664)
|
||||||
err = document.ReadBytes(resultBytes)
|
assert.NoError(t, err)
|
||||||
if err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// _ = os.WriteFile("/tmp/out3.docx", resultBytes, 0644) // TODO delete
|
|
||||||
|
|
||||||
checkAllFieldsPresent(t, document.GetContent(), data)
|
|
||||||
}
|
|
||||||
|
|
||||||
func checkAllFieldsPresent(t *testing.T, content string, data interface{}) {
|
|
||||||
t.Helper()
|
|
||||||
|
|
||||||
v := reflect.ValueOf(data)
|
|
||||||
vt := v.Type()
|
|
||||||
|
|
||||||
for i := 0; i < v.NumField(); i++ {
|
|
||||||
field := v.Field(i)
|
|
||||||
fieldName := vt.Field(i).Name
|
|
||||||
fieldValue := field.Interface()
|
|
||||||
|
|
||||||
switch x := fieldValue.(type) {
|
|
||||||
case string:
|
|
||||||
if !strings.Contains(content, x) {
|
|
||||||
t.Errorf("missing value for '%s': '%s'", fieldName, x)
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
t.Error("unhandled field")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
BIN
static/examples/docx/report.docx
Normal file
BIN
static/examples/docx/report.docx
Normal file
Binary file not shown.
72
tools/xml_doc.go
Normal file
72
tools/xml_doc.go
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
package tools
|
||||||
|
|
||||||
|
import (
|
||||||
|
"archive/zip"
|
||||||
|
"bytes"
|
||||||
|
"github.com/beevik/etree"
|
||||||
|
"io"
|
||||||
|
)
|
||||||
|
|
||||||
|
func ExtractDocx(file []byte) (map[string][]byte, error) {
|
||||||
|
archive, err := zip.NewReader(bytes.NewReader(file), int64(len(file)))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
files := make(map[string][]byte)
|
||||||
|
|
||||||
|
for _, f := range archive.File {
|
||||||
|
rc, err := f.Open()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
content, err := io.ReadAll(rc)
|
||||||
|
rc.Close()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
files[f.Name] = content
|
||||||
|
}
|
||||||
|
|
||||||
|
return files, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func CreateDocx(files map[string][]byte) ([]byte, error) {
|
||||||
|
var buf bytes.Buffer
|
||||||
|
zipWr := zip.NewWriter(&buf)
|
||||||
|
|
||||||
|
for name, content := range files {
|
||||||
|
file, err := zipWr.Create(name)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
_, err = file.Write(content)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
err := zipWr.Close()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return buf.Bytes(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func CreateTableCell(row *etree.Element, text string, fat bool) {
|
||||||
|
cell := row.CreateElement("w:tc")
|
||||||
|
tcPr := cell.CreateElement("w:tcPr")
|
||||||
|
tcPr.CreateElement("w:tcW").CreateAttr("w:w", "1000")
|
||||||
|
|
||||||
|
para := cell.CreateElement("w:p")
|
||||||
|
run := para.CreateElement("w:r")
|
||||||
|
|
||||||
|
if fat {
|
||||||
|
rPr := run.CreateElement("w:rPr")
|
||||||
|
rPr.CreateElement("w:b")
|
||||||
|
}
|
||||||
|
|
||||||
|
run.CreateElement("w:t").SetText(text)
|
||||||
|
cell.AddChild(para)
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user