194 lines
7.7 KiB
Plaintext
194 lines
7.7 KiB
Plaintext
Type xlsxComment = Class
|
|
///缺省构造函数
|
|
Function Create(sheet,excel); overload;
|
|
Begin
|
|
authors_ := array();
|
|
excel_ := excel;
|
|
sheetName_ := sheet;
|
|
[rid, commentFileName_, sheetFileName_, relsfile] := excel_.WorkBook().GetRelationshipRid(sheet, '../comments');
|
|
if commentFileName_ = '' then Begin
|
|
rid++;
|
|
rId_ := 'rId' + inttostr(rid);
|
|
commentId_ := excel_.WorkBook().GetFilesCount('xl/comments') + 1;
|
|
commentFileName_ := '../comments' + inttostr(commentId_) + '.xml';
|
|
xlCommentFileName := 'xl/comments' + inttostr(commentId_) + '.xml';
|
|
excel_.Zip().Add(xlCommentFileName, class(TSXml).XmlHeader() + '<comments xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"></comments>');
|
|
excel_.WorkBook().AddRelationshipRid(relsfile, commentFileName_, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments', rId_);
|
|
rid ++;
|
|
drawingVML_ := '../drawings/vmlDrawing' + inttostr(commentId_) + '.vml';
|
|
drawingVMLFile := 'xl/drawings/vmlDrawing' + inttostr(commentId_) + '.vml';
|
|
excel_.Zip().Remove(drawingVMLFile);
|
|
excel_.Zip().Add(drawingVMLFile, '<xml
|
|
xmlns:oa="urn:schemas-microsoft-com:office:activation"
|
|
xmlns:p="urn:schemas-microsoft-com:office:powerpoint"
|
|
xmlns:x="urn:schemas-microsoft-com:office:excel"
|
|
xmlns:o="urn:schemas-microsoft-com:office:office"
|
|
xmlns:v="urn:schemas-microsoft-com:vml">
|
|
<o:shapelayout v:ext="edit">
|
|
<o:idmap v:ext="edit" data="' + inttostr(commentId_) + '"/>
|
|
</o:shapelayout>
|
|
<v:shapetype id="_x0000_t202" coordsize="21600,21600" o:spt="202" path="m0,0l0,21600,21600,21600,21600,0xe">
|
|
<v:stroke joinstyle="miter"/>
|
|
<v:path gradientshapeok="t" o:connecttype="rect"/>
|
|
</v:shapetype>
|
|
</xml>');
|
|
excel_.WorkBook().AddRelationshipRid(relsfile, drawingVML_, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing', 'rId' + inttostr(rid));
|
|
content_xml := excel_.WorkBook().GetXmlFileObj(class(TSXml).GetFileName('Content_Types'));
|
|
class(TSXml).AddOverrideContentType(content_xml, '/' + xlCommentFileName, 'application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml');
|
|
class(TSXml).AddDefaultContentType(content_xml, 'vml', 'application/vnd.openxmlformats-officedocument.vmlDrawing');
|
|
|
|
sheetXml := excel_.WorkBook().GetSheetXmlfile(sheetName_).FirstChildElement('worksheet');
|
|
legacy := sheetXml.FirstChildElement('legacyDrawing');
|
|
if not ifObj(legacy) then legacy := sheetXml.InsertEndChild('element', 'legacyDrawing');
|
|
legacy.SetAttribute('r:id', 'rId' + inttostr(rid));
|
|
End
|
|
else Begin
|
|
rId_ := 'rId' + inttostr(rid);
|
|
xlCommentFileName := 'xl/' + ExtractFileName(commentFileName_);
|
|
s := RightStr(xlCommentFileName, length(xlCommentFileName) - 11);
|
|
commentId_ := strtoint(leftstr(s, length(s) - 4));
|
|
drawingVML_ := './drawings/vmlDrawing' + inttostr(commentId_) + '.vml';
|
|
End;
|
|
commentXmlFile_ := excel_.WorkBook().GetXmlFileObj(xlCommentFileName);
|
|
authors := commentXmlFile_.FirstChildElement('comments').FirstChildElement('authors');
|
|
if not ifObj(authors) then
|
|
authors := commentXmlFile_.FirstChildElement('comments').InsertEndChild('element', 'authors');
|
|
node := authors.FirstChildElement();
|
|
i := 0;
|
|
while ifObj(node) do Begin
|
|
author := node.GetText();
|
|
authors_[ author ] := i ++;
|
|
node := node.NextElement();
|
|
End;
|
|
initCommentObjs();
|
|
//println('sheet={},commentfile={},vmlfile={}',sheet, commentXmlFile_, drawingVML_);
|
|
End;
|
|
|
|
class Function NewObject(sheet, excel);
|
|
Begin
|
|
excel_ := excel;
|
|
o := excel_.WorkBook().GetSheetObj(sheet);//sheet存在
|
|
if not ifObj(o) then return 0;
|
|
return new xlsxComment(sheet, excel);
|
|
End;
|
|
|
|
Function AddComment(cell, author, comment);
|
|
Begin
|
|
authorId := authors_[author];
|
|
if not ifint(authorId) then Begin
|
|
authorId := length(authors_);
|
|
commentXmlFile_.FirstChildElement('comments').FirstChildElement('authors').InsertEndChild('element', 'author', author);//添加作者
|
|
authors_[author] := authorId;
|
|
End;
|
|
if not ifstring(comment) then return 'comment is not a string';
|
|
comments := TOfficeObj('TComments');
|
|
comments.Ref := cell;
|
|
comments.AuthorId := authorId;
|
|
authorObj := comments.AddComment(author + ':');
|
|
arr := str2array(comment, '\n');
|
|
colCount := length(author)+1;
|
|
for i:=0 to length(arr)-1 do Begin
|
|
line := TrimRight(arr[i]);
|
|
if length(line) > colCount then colCount := length(line);
|
|
End;
|
|
lineCount := length(arr);
|
|
commentObj := comments.AddComment('\n' + comment);
|
|
commentObj.Font.Bold := nil;
|
|
commentObj.Space := 'preserve';
|
|
domData := comments.Marshal();
|
|
node := commentObjs_[cell];
|
|
if ifObj(node) then
|
|
node.DeleteChildren();
|
|
else
|
|
node := commentXmlFile_.FirstChildElement('comments').FirstChildElement('commentList').InsertEndChild('element', 'comment');
|
|
node.UnMarshal(domData);
|
|
commentObjs_[cell] := node;
|
|
//commentXmlFile_.print;
|
|
innerxml := '<v:shape id="_x0000_s1025" o:spt="202" type="#_x0000_t202" style="position:absolute;left:0pt;top:0pt;margin-left:59.85pt;margin-top:1.5pt;height:60pt;width:97.5pt;visibility:hidden;" fillcolor="#FFFFE1" filled="t" stroked="t" o:insetmode="auto" coordsize="21600,21600">
|
|
<v:path/>
|
|
<v:fill on="t" color2="#FFFFFF" focussize="0,0"/>
|
|
<v:stroke color="#000000"/>
|
|
<v:imagedata o:title=""/>
|
|
<o:lock v:ext="edit" aspectratio="f"/>
|
|
<v:textbox style="direction:context;layout-flow:horizontal;mso-rotate:0;">
|
|
<div style="text-align:left"/>
|
|
</v:textbox>
|
|
<x:ClientData />
|
|
</v:shape>';
|
|
drawingVMLFile := 'xl/drawings/vmlDrawing' + inttostr(commentId_) + '.vml';
|
|
xmlObj := excel_.WorkBook().GetXmlFileObj(drawingVMLFile);
|
|
if ifObj(xmlObj) then Begin
|
|
node := xmlObj.LastChildElement('xml').InsertEndChild('element','v:shape');
|
|
node.UnMarshal(innerxml);
|
|
node := node.FirstChildElement('x:ClientData');
|
|
if ifObj(node) then Begin
|
|
[err, col, row] := excel_.CellNameToCoordinates(cell);
|
|
clientData := TOfficeObj('TClientData');
|
|
clientData.Anchor := fmt('{},23,{},0,{},{},{},5',col, row, 1+col+lineCount, colCount+col-1, 1+row+lineCount);
|
|
clientData.Row := row - 1;
|
|
ClientData.Column := col - 1;
|
|
node.UnMarshal(clientData.Marshal());
|
|
//xmlObj.Print;
|
|
End;
|
|
End;
|
|
return 'ok';
|
|
End;
|
|
|
|
Function GetComment(cell);
|
|
Begin
|
|
o := commentObjs_[cell];
|
|
if not ifObj(o) then return array(nil, nil);
|
|
r_node := o.FirstChildElement('text').FirstChildElement('r');
|
|
author := r_node.FirstChildElement('t').GetText();
|
|
if length(author) > 1 then author := author[:length(author)-1];
|
|
r_node := r_node.NextElement();
|
|
comment := '';
|
|
while ifObj(r_node) do
|
|
begin
|
|
comment += r_node.FirstChildElement('t').GetText();
|
|
r_node := r_node.NextElement();
|
|
end
|
|
if length(comment) > 1 then comment := comment[2:];
|
|
return array(author, comment);
|
|
End;
|
|
|
|
Function RemoveComment(cell);
|
|
Begin
|
|
node := commentObjs_[cell];
|
|
if ifObj(node) then
|
|
begin
|
|
commentXmlFile_.FirstChildElement('comments').FirstChildElement('commentList').DeleteChild(node);
|
|
commentObjs_[cell] := nil;
|
|
end
|
|
End;
|
|
|
|
private
|
|
|
|
Function initCommentObjs();
|
|
Begin
|
|
if not ifarray(commentObjs_) then Begin
|
|
commentObjs_ := array();
|
|
node := commentXmlFile_.FirstChildElement('comments').FirstChildElement('commentList');
|
|
if not ifObj(node) then
|
|
node := commentXmlFile_.FirstChildElement('comments').InsertEndChild('element','commentList');
|
|
node := node.FirstChildElement('comment');
|
|
while ifObj(node) do Begin
|
|
ref := node.GetAttribute('ref');
|
|
commentObjs_[ref] := node;
|
|
node := node.NextElement();
|
|
End;
|
|
End;
|
|
End;
|
|
|
|
authors_;
|
|
commentId_;
|
|
commentFileName_:string;//'../comments/comment1.xml'
|
|
drawingVML_:string;//'../drawings/vmlDrawing1.xml'
|
|
rId_:string;
|
|
sheetName_:string;//sheet名称
|
|
sheetFileName_;//xl/worksheets/sheetN.xml
|
|
excel_;//TSExcelFile对象
|
|
commentXmlFile_;//XmlFile对象
|
|
commentObjs_;
|
|
End;
|