urvin-compliance / caracal

Caracal is a ruby library for dynamically creating professional-quality Microsoft Word documents (.docx).
MIT License
322 stars 142 forks source link

Add support for header and footer content. #94

Open rishistrive opened 6 years ago

rishistrive commented 6 years ago

Hello team, Could you please tell me how can I add Image in footer.

saulomaximo commented 6 years ago

I need this feature. Following...

charles-marques commented 6 years ago

Hey @rishistrive @saulomaximo so do I.

I need the same functionality, but i don't know how to solve. Actualy, I need embeding image into document's header and footer. Following

jdugan commented 6 years ago

Hi, everyone.

I've renamed this issue because there's a long-standing desire to add header and footer support to Caracal, but so far no one--myself included--has implemented a complete solution to the problem.

When Caracal was originally written, the project that spawned it didn't need headers and footers, so the library's design didn't include them at all.1 The main issue is that headers and footers can accept any content the document body can. So, the solution really can't be just to add image support to headers, footnotes to footers, etc. Caracal really needs a holistic, reasonably defined way of separating header content from body content from footer content. Then, we should be able to use all the same commands inside each of those contexts that we currently use for the document body. Doing all that will require significant changes to the DSL, the documentation, the data modelling, and the rendering. It will be a major bump with backward-incompatible changes.

There is a current PR that implements a demonstration of the basic approach I think makes sense. It is far from complete and involves some techniques the author himself describes as hacks. (No disrespect to @ysbaddaden. This PR is pretty impressive, considering how little time he invested in it.) Ideally, I'd like to see this approach expanded so that Caracal accepts document commands in a more structured way. Then we can segment document configuration, header, body, and footer content properly in the modelling and rendering. Maybe something more like the following:

docx.config do
  # page margins, orientation, custom styles, etc
end

docx.header do
  # all header content goes here
end

docx.body do
  # all body content goes here
end

docx.footer do
  # all footer content goes here
end

I am 100% open to discussion on the matter. (Maybe you have a better approach?) And I'm happy to provide guidance to anyone willing to tackle the problem properly.

Frankly, anyone who successfully saw this change all the way to being merged would be made a collaborator. At that point, they'd know as much about the library as I do. :)


1 This explains why page numbers are implemented so poorly.

charles-marques commented 6 years ago

Thank you @jdugan!! I will follow your recommendations and try currentPR!

charles-marques commented 6 years ago

About the name of issue, In fact, the main question is the using of header and footer, because we need a solution to use this part of document. I'm really glad you answer the issue and help us! I will report you if i have some dificult or problems. Thank you!

goulvench commented 4 years ago

Hi all, I forked the project to add this functionality for a client app, and would like to contribute what I can for Caracal to do this natively.

I used what was done in PR #112 but used a three-column table and the align property to assign contents to each column. Maybe not the best approach, but it works for the project where I use it.

To note: in Caracal's current state, the header xml file is not generated when page numbers are not set dut to this check in document_renderer.rb. Easy fix but it took me a while to understand why headers were not showing up when I tested with a simple document.

Please let me know what would be the best way to contribute to this project and functionality :-)

kinjal-12 commented 2 years ago

Hi @goulvench, I've taken reference to add header into the word file for Caracal from PR https://github.com/urvin-compliance/caracal/pull/112. But currently I'm facing issue with inlining image with header text. Here is my code,

docx.header.img image_path do align :left width 60 height 60 end

docx.header.p organization_name do align :right bold true end

And here is the output word file where it is not showing inline.,

Screenshot 2022-04-13 at 6 15 01 PM

I'm trying to get text to show up in-line with an image using the Caracal ruby gem like this. how can I achieve this behaviour with caracal? (accomplished in Word by going to Format Picture -> Wrap Text -> In Front of Text)

Screenshot 2022-04-13 at 6 30 11 PM
goulvench commented 2 years ago

@kinjal-12 Sorry, I haven't used Caracal in 2 years, I can't really help you there. Feel free to have a look at what I did in my fork. As documented there, I used a three-column table in the header, and used the align property to place contents in any of those columns. Alignment in particular was added to my fork in this commit.

kinjal-12 commented 2 years ago

Thank you very much @goulvench. I referred your commit and followed the idea of adding a table inside the header. I ended up doing the following code to make it work. embedding it for future reference.

header_logo = Caracal::Core::Models::TableCellModel.new do img "path of image", width: 70, height: 50 end

org_name = Caracal::Core::Models::TableCellModel.new do p organization_name end

I've created two-dimensional array to make it work.

docx.header.table [[header_logo, org_name]] do cell_style rows[0][0], colspan: 2 end

kinjal-12 commented 2 years ago

I wonder if anyone is having an idea about implementing the feature for headers in .docx which looks like this to implement "Different First Page" setting in the WORD.

Screenshot 2022-06-15 at 4 52 43 PM

@goulvench, As of now changes for contents in the header and footer are applying to all the pages. However, I want to implement a different header on the first page only. Are there any known changes for you to support this setting in Caracal renderers?

Screenshot 2022-06-15 at 5 10 50 PM
goulvench commented 2 years ago

Hi @kinjal-12, I'm no longer familiar with that code but it seems to be a two-fold solution:

  1. When defining header content, store if this content should be added to the first page only (using a boolean).
  2. When generating the final XML, branch according to the presence of different content for the first page.

Step 1 should be easy-ish, but step 2 might require disassembling a valid Word document to see what gets generated, and trying to get Caracal to output it. Good luck with that, as Word's parser is very finicky! For instance, the order of tags and attributes may matter…