import moment from 'moment/min/moment-with-locales' ;
import { TAPi18n } from '/imports/i18n' ;
import { createWorkbook } from './createWorkbook' ;
// exporter maybe is broken since Gridfs introduced, add fs and path
class ExporterExcel {
constructor ( boardId , userLanguage ) {
this . _boardId = boardId ;
this . userLanguage = userLanguage ;
}
build ( res ) {
const fs = Npm . require ( 'fs' ) ;
const os = Npm . require ( 'os' ) ;
const path = Npm . require ( 'path' ) ;
const byBoard = {
boardId : this . _boardId ,
} ;
const byBoardNoLinked = {
boardId : this . _boardId ,
linkedId : {
$in : [ '' , null ] ,
} ,
} ;
// we do not want to retrieve boardId in related elements
const noBoardId = {
fields : {
boardId : 0 ,
} ,
} ;
const result = {
_format : 'wekan-board-1.0.0' ,
} ;
_ . extend (
result ,
Boards . findOne ( this . _boardId , {
fields : {
stars : 0 ,
} ,
} ) ,
) ;
result . lists = Lists . find ( byBoard , noBoardId ) . fetch ( ) ;
result . cards = Cards . find ( byBoardNoLinked , noBoardId ) . fetch ( ) ;
result . swimlanes = Swimlanes . find ( byBoard , noBoardId ) . fetch ( ) ;
result . customFields = CustomFields . find (
{
boardIds : {
$in : [ this . boardId ] ,
} ,
} ,
{
fields : {
boardId : 0 ,
} ,
} ,
) . fetch ( ) ;
result . comments = CardComments . find ( byBoard , noBoardId ) . fetch ( ) ;
result . activities = Activities . find ( byBoard , noBoardId ) . fetch ( ) ;
result . rules = Rules . find ( byBoard , noBoardId ) . fetch ( ) ;
result . checklists = [ ] ;
result . checklistItems = [ ] ;
result . subtaskItems = [ ] ;
result . triggers = [ ] ;
result . actions = [ ] ;
result . cards . forEach ( ( card ) => {
result . checklists . push (
... Checklists . find ( {
cardId : card . _id ,
} ) . fetch ( ) ,
) ;
result . checklistItems . push (
... ChecklistItems . find ( {
cardId : card . _id ,
} ) . fetch ( ) ,
) ;
result . subtaskItems . push (
... Cards . find ( {
parentId : card . _id ,
} ) . fetch ( ) ,
) ;
} ) ;
result . rules . forEach ( ( rule ) => {
result . triggers . push (
... Triggers . find (
{
_id : rule . triggerId ,
} ,
noBoardId ,
) . fetch ( ) ,
) ;
result . actions . push (
... Actions . find (
{
_id : rule . actionId ,
} ,
noBoardId ,
) . fetch ( ) ,
) ;
} ) ;
// we also have to export some user data - as the other elements only
// include id but we have to be careful:
// 1- only exports users that are linked somehow to that board
// 2- do not export any sensitive information
const users = { } ;
result . members . forEach ( ( member ) => {
users [ member . userId ] = true ;
} ) ;
result . lists . forEach ( ( list ) => {
users [ list . userId ] = true ;
} ) ;
result . cards . forEach ( ( card ) => {
users [ card . userId ] = true ;
if ( card . members ) {
card . members . forEach ( ( memberId ) => {
users [ memberId ] = true ;
} ) ;
}
if ( card . assignees ) {
card . assignees . forEach ( ( memberId ) => {
users [ memberId ] = true ;
} ) ;
}
} ) ;
result . comments . forEach ( ( comment ) => {
users [ comment . userId ] = true ;
} ) ;
result . activities . forEach ( ( activity ) => {
users [ activity . userId ] = true ;
} ) ;
result . checklists . forEach ( ( checklist ) => {
users [ checklist . userId ] = true ;
} ) ;
const byUserIds = {
_id : {
$in : Object . getOwnPropertyNames ( users ) ,
} ,
} ;
// we use whitelist to be sure we do not expose inadvertently
// some secret fields that gets added to User later.
const userFields = {
fields : {
_id : 1 ,
username : 1 ,
'profile.initials' : 1 ,
'profile.avatarUrl' : 1 ,
} ,
} ;
result . users = Users . find ( byUserIds , userFields )
. fetch ( )
. map ( ( user ) => {
// user avatar is stored as a relative url, we export absolute
if ( ( user . profile || { } ) . avatarUrl ) {
user . profile . avatarUrl = FlowRouter . url ( user . profile . avatarUrl ) ;
}
return user ;
} ) ;
//init exceljs workbook
const workbook = createWorkbook ( ) ;
workbook . creator = TAPi18n . _ _ ( 'export-board' , '' , this . userLanguage ) ;
workbook . lastModifiedBy = TAPi18n . _ _ ( 'export-board' , '' , this . userLanguage ) ;
workbook . created = new Date ( ) ;
workbook . modified = new Date ( ) ;
workbook . lastPrinted = new Date ( ) ;
const filename = ` ${ result . title } .xlsx ` ;
//init worksheet
let worksheetTitle = result . title ;
if ( worksheetTitle . length > 31 ) {
// MS Excel doesn't allow worksheet name longer than 31 chars
// Exceljs truncate names to 31 chars
let words = worksheetTitle . split ( ' ' ) ;
let tmpTitle = '' ;
for ( let i = 0 ; i < words . length ; i ++ ) {
if ( words [ 0 ] . length > 27 ) {
// title has no spaces
tmpTitle = words [ 0 ] . substr ( 0 , 27 ) + ' ' ;
break ;
}
if ( tmpTitle . length + words [ i ] . length < 27 ) {
tmpTitle += words [ i ] + ' ' ;
}
else {
break ;
}
}
worksheetTitle = tmpTitle + '...' ;
}
const worksheet = workbook . addWorksheet ( worksheetTitle , {
properties : {
tabColor : {
argb : 'FFC0000' ,
} ,
} ,
pageSetup : {
paperSize : 9 ,
orientation : 'landscape' ,
} ,
} ) ;
//get worksheet
const ws = workbook . getWorksheet ( worksheetTitle ) ;
ws . properties . defaultRowHeight = 20 ;
//init columns
//Excel font. Western: Arial. zh-CN: 宋体
ws . columns = [
{
key : 'a' ,
width : 14 ,
} ,
{
key : 'b' ,
width : 40 ,
} ,
{
key : 'c' ,
width : 60 ,
} ,
{
key : 'd' ,
width : 40 ,
} ,
{
key : 'e' ,
width : 20 ,
} ,
{
key : 'f' ,
width : 20 ,
style : {
font : {
name : TAPi18n . _ _ ( 'excel-font' ) ,
size : '10' ,
} ,
numFmt : 'yyyy/mm/dd hh:mm:ss' ,
} ,
} ,
{
key : 'g' ,
width : 20 ,
style : {
font : {
name : TAPi18n . _ _ ( 'excel-font' ) ,
size : '10' ,
} ,
numFmt : 'yyyy/mm/dd hh:mm:ss' ,
} ,
} ,
{
key : 'h' ,
width : 20 ,
style : {
font : {
name : TAPi18n . _ _ ( 'excel-font' ) ,
size : '10' ,
} ,
numFmt : 'yyyy/mm/dd hh:mm:ss' ,
} ,
} ,
{
key : 'i' ,
width : 20 ,
style : {
font : {
name : TAPi18n . _ _ ( 'excel-font' ) ,
size : '10' ,
} ,
numFmt : 'yyyy/mm/dd hh:mm:ss' ,
} ,
} ,
{
key : 'j' ,
width : 20 ,
style : {
font : {
name : TAPi18n . _ _ ( 'excel-font' ) ,
size : '10' ,
} ,
numFmt : 'yyyy/mm/dd hh:mm:ss' ,
} ,
} ,
{
key : 'k' ,
width : 20 ,
style : {
font : {
name : TAPi18n . _ _ ( 'excel-font' ) ,
size : '10' ,
} ,
numFmt : 'yyyy/mm/dd hh:mm:ss' ,
} ,
} ,
{
key : 'l' ,
width : 20 ,
} ,
{
key : 'm' ,
width : 20 ,
} ,
{
key : 'n' ,
width : 20 ,
} ,
{
key : 'o' ,
width : 20 ,
} ,
{
key : 'p' ,
width : 20 ,
} ,
{
key : 'q' ,
width : 20 ,
} ,
{
key : 'r' ,
width : 20 ,
} ,
] ;
//add title line
ws . mergeCells ( 'A1:H1' ) ;
ws . getCell ( 'A1' ) . value = result . title ;
ws . getCell ( 'A1' ) . style = {
font : {
name : TAPi18n . _ _ ( 'excel-font' ) ,
size : '20' ,
} ,
} ;
ws . getCell ( 'A1' ) . alignment = {
vertical : 'middle' ,
horizontal : 'left' ,
} ;
ws . getRow ( 1 ) . height = 40 ;
//get member and assignee info
let jmem = '' ;
let jassig = '' ;
const jmeml = { } ;
const jassigl = { } ;
for ( const i in result . users ) {
jmem = ` ${ jmem + result . users [ i ] . username } , ` ;
jmeml [ result . users [ i ] . _id ] = result . users [ i ] . username ;
}
jmem = jmem . substr ( 0 , jmem . length - 1 ) ;
for ( const ia in result . users ) {
jassig = ` ${ jassig + result . users [ ia ] . username } , ` ;
jassigl [ result . users [ ia ] . _id ] = result . users [ ia ] . username ;
}
jassig = jassig . substr ( 0 , jassig . length - 1 ) ;
//get kanban list info
const jlist = { } ;
for ( const klist in result . lists ) {
jlist [ result . lists [ klist ] . _id ] = result . lists [ klist ] . title ;
}
//get kanban swimlanes info
const jswimlane = { } ;
for ( const kswimlane in result . swimlanes ) {
jswimlane [ result . swimlanes [ kswimlane ] . _id ] =
result . swimlanes [ kswimlane ] . title ;
}
//get kanban label info
const jlabel = { } ;
var isFirst = 1 ;
for ( const klabel in result . labels ) {
// console.log(klabel);
if ( isFirst == 0 ) {
jlabel [ result . labels [ klabel ] . _id ] = ` , ${ result . labels [ klabel ] . name } ` ;
} else {
isFirst = 0 ;
jlabel [ result . labels [ klabel ] . _id ] = result . labels [ klabel ] . name ;
}
}
//add data +8 hours
function addTZhours ( jdate ) {
if ( ! jdate ) { return ' ' ; }
const curdate = new Date ( jdate ) ;
const checkCorrectDate = moment ( curdate ) ;
if ( checkCorrectDate . isValid ( ) ) {
return curdate ;
} else {
return ' ' ;
}
////Do not add 8 hours to GMT. Use GMT instead.
////Could not yet figure out how to get localtime.
//return new Date(curdate.setHours(curdate.getHours() + 8));
//return curdate;
}
//cell center
function cellCenter ( cellno ) {
ws . getCell ( cellno ) . alignment = {
vertical : 'middle' ,
horizontal : 'center' ,
wrapText : true ,
} ;
}
function cellLeft ( cellno ) {
ws . getCell ( cellno ) . alignment = {
vertical : 'middle' ,
horizontal : 'left' ,
wrapText : true ,
} ;
}
// cell Card alignment
function cellCardAlignment ( cellno ) {
ws . getCell ( cellno ) . alignment = {
vertical : 'top' ,
horizontal : 'left' ,
wrapText : true ,
} ;
}
//all border
function allBorder ( cellno ) {
ws . getCell ( cellno ) . border = {
top : {
style : 'thin' ,
} ,
left : {
style : 'thin' ,
} ,
bottom : {
style : 'thin' ,
} ,
right : {
style : 'thin' ,
} ,
} ;
}
//add blank row
ws . addRow ( ) . values = [ '' , '' , '' , '' , '' , '' ] ;
//add board description
ws . addRow ( ) . values = [
TAPi18n . _ _ ( 'description' , '' , this . userLanguage ) ,
result . description ,
] ;
ws . mergeCells ( 'B3:H3' ) ;
ws . getRow ( 3 ) . height = 40 ;
// In MS Excel, we can't use the AutoFit feature on a column that contains a cell merged with cells in other columns.
// Likewise, we can't use AutoFit on a row that contains a cell merged with cells in other rows.
ws . getRow ( 3 ) . font = {
name : TAPi18n . _ _ ( 'excel-font' ) ,
size : 10 ,
} ;
ws . getCell ( 'A3' ) . style = {
font : {
name : TAPi18n . _ _ ( 'excel-font' ) ,
size : '10' ,
bold : true ,
} ,
} ;
ws . getCell ( ` B3 ` ) . alignment = {
wrapText : true ,
vertical : 'middle' ,
} ;
cellCenter ( 'A3' ) ;
//add blank row
ws . addRow ( ) . values = [ '' , '' , '' , '' , '' , '' ] ;
//add kanban info
ws . addRow ( ) . values = [
TAPi18n . _ _ ( 'createdAt' , '' , this . userLanguage ) ,
addTZhours ( result . createdAt ) ,
TAPi18n . _ _ ( 'modifiedAt' , '' , this . userLanguage ) ,
addTZhours ( result . modifiedAt ) ,
TAPi18n . _ _ ( 'members' , '' , this . userLanguage ) ,
jmem ,
] ;
ws . getRow ( 5 ) . font = {
name : TAPi18n . _ _ ( 'excel-font' ) ,
size : 10 ,
bold : true ,
} ;
ws . mergeCells ( 'F5:R5' ) ;
ws . getCell ( 'B5' ) . style = {
font : {
name : TAPi18n . _ _ ( 'excel-font' ) ,
size : '10' ,
bold : true ,
} ,
numFmt : 'yyyy/mm/dd hh:mm:ss' ,
} ;
ws . getCell ( 'D5' ) . style = {
font : {
name : TAPi18n . _ _ ( 'excel-font' ) ,
size : '10' ,
bold : true ,
} ,
numFmt : 'yyyy/mm/dd hh:mm:ss' ,
} ;
cellCenter ( 'A5' ) ;
cellCenter ( 'B5' ) ;
cellCenter ( 'C5' ) ;
cellCenter ( 'D5' ) ;
cellCenter ( 'E5' ) ;
cellLeft ( 'F5' ) ;
ws . getRow ( 5 ) . height = 20 ;
allBorder ( 'A5' ) ;
allBorder ( 'B5' ) ;
allBorder ( 'C5' ) ;
allBorder ( 'D5' ) ;
allBorder ( 'E5' ) ;
allBorder ( 'F5' ) ;
//add blank row
ws . addRow ( ) . values = [
'' ,
'' ,
'' ,
'' ,
'' ,
'' ,
'' ,
'' ,
'' ,
'' ,
'' ,
'' ,
'' ,
'' ,
'' ,
] ;
//add card title
//ws.addRow().values = ['编号', '标题', '创建人', '创建时间', '更新时间', '列表', '成员', '描述', '标签'];
//this is where order in which the excel file generates
ws . addRow ( ) . values = [
TAPi18n . _ _ ( 'number' , '' , this . userLanguage ) ,
TAPi18n . _ _ ( 'title' , '' , this . userLanguage ) ,
TAPi18n . _ _ ( 'description' , '' , this . userLanguage ) ,
TAPi18n . _ _ ( 'parent-card' , '' , this . userLanguage ) ,
TAPi18n . _ _ ( 'owner' , '' , this . userLanguage ) ,
TAPi18n . _ _ ( 'createdAt' , '' , this . userLanguage ) ,
TAPi18n . _ _ ( 'last-modified-at' , '' , this . userLanguage ) ,
TAPi18n . _ _ ( 'card-received' , '' , this . userLanguage ) ,
TAPi18n . _ _ ( 'card-start' , '' , this . userLanguage ) ,
TAPi18n . _ _ ( 'card-due' , '' , this . userLanguage ) ,
TAPi18n . _ _ ( 'card-end' , '' , this . userLanguage ) ,
TAPi18n . _ _ ( 'list' , '' , this . userLanguage ) ,
TAPi18n . _ _ ( 'swimlane' , '' , this . userLanguage ) ,
TAPi18n . _ _ ( 'assignee' , '' , this . userLanguage ) ,
TAPi18n . _ _ ( 'members' , '' , this . userLanguage ) ,
TAPi18n . _ _ ( 'labels' , '' , this . userLanguage ) ,
TAPi18n . _ _ ( 'overtime-hours' , '' , this . userLanguage ) ,
TAPi18n . _ _ ( 'spent-time-hours' , '' , this . userLanguage ) ,
] ;
ws . getRow ( 7 ) . height = 20 ;
allBorder ( 'A7' ) ;
allBorder ( 'B7' ) ;
allBorder ( 'C7' ) ;
allBorder ( 'D7' ) ;
allBorder ( 'E7' ) ;
allBorder ( 'F7' ) ;
allBorder ( 'G7' ) ;
allBorder ( 'H7' ) ;
allBorder ( 'I7' ) ;
allBorder ( 'J7' ) ;
allBorder ( 'K7' ) ;
allBorder ( 'L7' ) ;
allBorder ( 'M7' ) ;
allBorder ( 'N7' ) ;
allBorder ( 'O7' ) ;
allBorder ( 'P7' ) ;
allBorder ( 'Q7' ) ;
allBorder ( 'R7' ) ;
cellCenter ( 'A7' ) ;
cellCenter ( 'B7' ) ;
cellCenter ( 'C7' ) ;
cellCenter ( 'D7' ) ;
cellCenter ( 'E7' ) ;
cellCenter ( 'F7' ) ;
cellCenter ( 'G7' ) ;
cellCenter ( 'H7' ) ;
cellCenter ( 'I7' ) ;
cellCenter ( 'J7' ) ;
cellCenter ( 'K7' ) ;
cellCenter ( 'L7' ) ;
cellCenter ( 'M7' ) ;
cellCenter ( 'N7' ) ;
cellCenter ( 'O7' ) ;
cellCenter ( 'P7' ) ;
cellCenter ( 'Q7' ) ;
cellCenter ( 'R7' ) ;
ws . getRow ( 7 ) . font = {
name : TAPi18n . _ _ ( 'excel-font' ) ,
size : 10 ,
bold : true ,
} ;
//add blank row
//add card info
for ( const i in result . cards ) {
const jcard = result . cards [ i ] ;
//get member info
let jcmem = '' ;
for ( const j in jcard . members ) {
jcmem += jmeml [ jcard . members [ j ] ] ;
jcmem += ' ' ;
}
//get assignee info
let jcassig = '' ;
for ( const ja in jcard . assignees ) {
jcassig += jassigl [ jcard . assignees [ ja ] ] ;
jcassig += ' ' ;
}
//get card label info
let jclabel = '' ;
for ( const jl in jcard . labelIds ) {
jclabel += jlabel [ jcard . labelIds [ jl ] ] ;
jclabel += ' ' ;
}
//get parent name
if ( jcard . parentId ) {
const parentCard = result . cards . find (
( card ) => card . _id === jcard . parentId ,
) ;
jcard . parentCardTitle = parentCard ? parentCard . title : '' ;
}
//add card detail
const t = Number ( i ) + 1 ;
ws . addRow ( ) . values = [
t . toString ( ) ,
jcard . title ,
jcard . description ,
jcard . parentCardTitle ,
jmeml [ jcard . userId ] ,
addTZhours ( jcard . createdAt ) ,
addTZhours ( jcard . dateLastActivity ) ,
addTZhours ( jcard . receivedAt ) ,
addTZhours ( jcard . startAt ) ,
addTZhours ( jcard . dueAt ) ,
addTZhours ( jcard . endAt ) ,
jlist [ jcard . listId ] ,
jswimlane [ jcard . swimlaneId ] ,
jcassig ,
jcmem ,
jclabel ,
jcard . isOvertime ? 'true' : 'false' ,
jcard . spentTime ,
] ;
const y = Number ( i ) + 8 ;
//ws.getRow(y).height = 25;
ws . getRow ( y ) . font = {
name : TAPi18n . _ _ ( 'excel-font' ) ,
size : 10 ,
} ;
// Border
allBorder ( ` A ${ y } ` ) ;
allBorder ( ` B ${ y } ` ) ;
allBorder ( ` C ${ y } ` ) ;
allBorder ( ` D ${ y } ` ) ;
allBorder ( ` E ${ y } ` ) ;
allBorder ( ` F ${ y } ` ) ;
allBorder ( ` G ${ y } ` ) ;
allBorder ( ` H ${ y } ` ) ;
allBorder ( ` I ${ y } ` ) ;
allBorder ( ` J ${ y } ` ) ;
allBorder ( ` K ${ y } ` ) ;
allBorder ( ` L ${ y } ` ) ;
allBorder ( ` M ${ y } ` ) ;
allBorder ( ` N ${ y } ` ) ;
allBorder ( ` O ${ y } ` ) ;
allBorder ( ` P ${ y } ` ) ;
allBorder ( ` Q ${ y } ` ) ;
allBorder ( ` R ${ y } ` ) ;
// Alignment
ws . getCell ( ` A ${ y } ` ) . alignment = {
vertical : 'top' ,
horizontal : 'right' ,
wrapText : true ,
} ;
cellCardAlignment ( ` B ${ y } ` ) ;
cellCardAlignment ( ` C ${ y } ` ) ;
cellCardAlignment ( ` D ${ y } ` ) ;
cellCardAlignment ( ` E ${ y } ` ) ;
cellCardAlignment ( ` F ${ y } ` ) ;
cellCardAlignment ( ` G ${ y } ` ) ;
cellCardAlignment ( ` H ${ y } ` ) ;
cellCardAlignment ( ` I ${ y } ` ) ;
cellCardAlignment ( ` J ${ y } ` ) ;
cellCardAlignment ( ` K ${ y } ` ) ;
cellCardAlignment ( ` L ${ y } ` ) ;
cellCardAlignment ( ` M ${ y } ` ) ;
cellCardAlignment ( ` N ${ y } ` ) ;
cellCardAlignment ( ` O ${ y } ` ) ;
cellCardAlignment ( ` P ${ y } ` ) ;
ws . getCell ( ` Q ${ y } ` ) . alignment = {
vertical : 'top' ,
horizontal : 'center' ,
wrapText : true ,
} ;
ws . getCell ( ` R ${ y } ` ) . alignment = {
vertical : 'top' ,
horizontal : 'center' ,
wrapText : true ,
} ;
}
//Activities worksheet
//init worksheet
const worksheet2 = workbook . addWorksheet ( TAPi18n . _ _ ( 'activity' , '' , this . userLanguage ) , {
properties : {
tabColor : {
argb : 'FFC0000' ,
} ,
} ,
pageSetup : {
paperSize : 9 ,
orientation : 'landscape' ,
} ,
} ) ;
//get worksheet
const ws2 = workbook . getWorksheet ( TAPi18n . _ _ ( 'activity' , '' , this . userLanguage ) ) ;
ws2 . properties . defaultRowHeight = 20 ;
//init columns
ws2 . columns = [
{
key : 'a' ,
width : 14 ,
} ,
{
key : 'b' ,
width : 60 ,
} ,
{
key : 'c' ,
width : 40 ,
} ,
{
key : 'd' ,
width : 40 ,
} ,
{
key : 'e' ,
width : 30 ,
style : {
font : {
name : TAPi18n . _ _ ( 'excel-font' ) ,
size : '10' ,
} ,
numFmt : 'yyyy/mm/dd hh:mm:ss' ,
} ,
} ,
{
key : 'f' ,
width : 30 ,
style : {
font : {
name : TAPi18n . _ _ ( 'excel-font' ) ,
size : '10' ,
} ,
numFmt : 'yyyy/mm/dd hh:mm:ss' ,
} ,
} ,
] ;
// cell Card alignment
function cellCardAlignmentWs2 ( cellno ) {
ws2 . getCell ( cellno ) . alignment = {
vertical : 'top' ,
horizontal : 'left' ,
wrapText : true ,
} ;
}
//all border
function allBorderWs2 ( cellno ) {
ws2 . getCell ( cellno ) . border = {
top : {
style : 'thin' ,
} ,
left : {
style : 'thin' ,
} ,
bottom : {
style : 'thin' ,
} ,
right : {
style : 'thin' ,
} ,
} ;
}
//add title line
ws2 . mergeCells ( 'A1:F1' ) ;
ws2 . getCell ( 'A1' ) . value = result . title ;
ws2 . getCell ( 'A1' ) . style = {
font : {
name : TAPi18n . _ _ ( 'excel-font' ) ,
size : '20' ,
} ,
} ;
ws2 . getCell ( 'A1' ) . alignment = {
vertical : 'middle' ,
horizontal : 'center' ,
wrapText : true ,
} ;
ws2 . getRow ( 1 ) . height = 40 ;
//add blank row
ws2 . addRow ( ) . values = [ '' , '' , '' , '' , '' , '' ] ;
//add comment title
ws2 . addRow ( ) . values = [
TAPi18n . _ _ ( 'number' , '' , this . userLanguage ) ,
TAPi18n . _ _ ( 'activity' , '' , this . userLanguage ) ,
TAPi18n . _ _ ( 'card' , '' , this . userLanguage ) ,
TAPi18n . _ _ ( 'owner' , '' , this . userLanguage ) ,
TAPi18n . _ _ ( 'createdAt' , '' , this . userLanguage ) ,
TAPi18n . _ _ ( 'last-modified-at' , '' , this . userLanguage ) ,
] ;
ws2 . getRow ( 3 ) . height = 20 ;
ws2 . getRow ( 3 ) . font = {
name : TAPi18n . _ _ ( 'excel-font' ) ,
size : 10 ,
bold : true ,
} ;
ws2 . getRow ( 3 ) . alignment = {
vertical : 'middle' ,
horizontal : 'center' ,
wrapText : true ,
} ;
allBorderWs2 ( 'A3' ) ;
allBorderWs2 ( 'B3' ) ;
allBorderWs2 ( 'C3' ) ;
allBorderWs2 ( 'D3' ) ;
allBorderWs2 ( 'E3' ) ;
allBorderWs2 ( 'F3' ) ;
//add comment info
let commentcnt = 0 ;
for ( const i in result . comments ) {
const jcomment = result . comments [ i ] ;
//card title
const parentCard = result . cards . find (
( card ) => card . _id === jcomment . cardId ,
) ;
jcomment . cardTitle = parentCard ? parentCard . title : '' ;
if ( jcomment . cardTitle == '' ) {
continue ;
}
//add comment detail
commentcnt ++ ;
ws2 . addRow ( ) . values = [
commentcnt . toString ( ) ,
jcomment . text ,
jcomment . cardTitle ,
jmeml [ jcomment . userId ] ,
addTZhours ( jcomment . createdAt ) ,
addTZhours ( jcomment . modifiedAt ) ,
] ;
const y = commentcnt + 3 ;
ws2 . getRow ( y ) . font = {
name : TAPi18n . _ _ ( 'excel-font' ) ,
size : 10 ,
} ;
// Border
allBorderWs2 ( ` A ${ y } ` ) ;
allBorderWs2 ( ` B ${ y } ` ) ;
allBorderWs2 ( ` C ${ y } ` ) ;
allBorderWs2 ( ` D ${ y } ` ) ;
allBorderWs2 ( ` E ${ y } ` ) ;
allBorderWs2 ( ` F ${ y } ` ) ;
// Alignment
ws2 . getCell ( ` A ${ y } ` ) . alignment = {
vertical : 'top' ,
horizontal : 'right' ,
wrapText : true ,
} ;
cellCardAlignmentWs2 ( ` B ${ y } ` ) ;
cellCardAlignmentWs2 ( ` C ${ y } ` ) ;
cellCardAlignmentWs2 ( ` D ${ y } ` ) ;
cellCardAlignmentWs2 ( ` E ${ y } ` ) ;
cellCardAlignmentWs2 ( ` F ${ y } ` ) ;
}
workbook . xlsx . write ( res ) . then ( function ( ) { } ) ;
}
canExport ( user ) {
const board = Boards . findOne ( this . _boardId ) ;
return board && board . isVisibleBy ( user ) ;
}
}
export { ExporterExcel } ;